SQL - 填充组表

时间:2011-05-20 17:10:28

标签: sql tsql sql-server-2008 data-warehouse dimensions

给出以下表格/关系

enter image description here

编辑:如果使用下面的SQL填充,则应返回此....

enter image description here

SELECT     TOP (100) PERCENT dbo.Task.Name AS Expr1, dbo.Role.Name FROM dbo.Role INNER JOIN dbo.RoleTask ON dbo.Role.Id = dbo.RoleTask.RoleId INNER JOIN                       dbo.Task ON dbo.RoleTask.TaskId = dbo.Task.Id ORDER BY dbo.Task.Name, dbo.Role.Name

目标

我正在尝试使用Role和Task之间的多对多关系定义的角色组来填充RoleGroup(刚刚挂在那里!),并认识到某些角色可能已经在RoleGroup表中。

编辑:所以,考虑到上面的示例结果,这是我需要在RoleGroup中看到的内容(我已经修改了这个,因为原始帖子有希望让我更清楚我是什么试图实现... ...

GroupId      RoleId
1            Plumber
2            Gardener
2            Topiary Guru
3            Electrician
4            Cleaner
4            Housekeeping Supervisor
4            Toilet Cleaning Specialist  
5            Housekeeping Supervisor

结果说明

由于角色已与某些任务相关联,因此可以识别角色组。

在我的例子中,“清洁工,家政监督员和厕所清洁专家”都与“厕所清洁”任务有关。因此,我可以说这是一个群体,并希望提取这些信息。

同样,“管家监督员”与“厕所检查”任务有关;没有其他角色。这意味着应该提取另一个新组(2 - 管家监督员)。

如果“管家监督员”与另一项任务相关联,而没有其他任务,我就不需要创建另一个团体,因为它已被识别。

哦,我正在尝试使用SQL Server 2008中的SQL实现此目的。

任何提示或提示表示赞赏。

SQL

USE TestDatabase
GO

CREATE TABLE [dbo].[Task](
    [Id] [int] NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_Type] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Department](
    [Id] [int] NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
 CONSTRAINT [PK_Department] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[RoleGroup](
    [Id] [int] NOT NULL,
    [RoleId] [int] NOT NULL
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[Role](
    [Id] [int] NOT NULL,
    [Name] [nvarchar](50) NOT NULL,
    [DepartmentId] [int] NOT NULL,
 CONSTRAINT [PK_Role] PRIMARY KEY CLUSTERED 
(
    [Id] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO

CREATE TABLE [dbo].[RoleTask](
    [RoleId] [int] NOT NULL,
    [TaskId] [int] NOT NULL,
 CONSTRAINT [PK_RoleTask] PRIMARY KEY CLUSTERED 
(
    [RoleId] ASC,
    [TaskId] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]
GO
/****** Object:  ForeignKey [FK_Role_Department]    Script Date: 05/20/2011 17:56:49 ******/
ALTER TABLE [dbo].[Role]  WITH CHECK ADD  CONSTRAINT [FK_Role_Department] FOREIGN KEY([DepartmentId])
REFERENCES [dbo].[Department] ([Id])
GO
ALTER TABLE [dbo].[Role] CHECK CONSTRAINT [FK_Role_Department]
GO

/****** Object:  ForeignKey [FK_RoleTask_Role]    Script Date: 05/20/2011 17:56:49 ******/
ALTER TABLE [dbo].[RoleTask]  WITH CHECK ADD  CONSTRAINT [FK_RoleTask_Role] FOREIGN KEY([RoleId])
REFERENCES [dbo].[Role] ([Id])
GO
ALTER TABLE [dbo].[RoleTask] CHECK CONSTRAINT [FK_RoleTask_Role]
GO

/****** Object:  ForeignKey [FK_RoleTask_Task]    Script Date: 05/20/2011 17:56:49 ******/
ALTER TABLE [dbo].[RoleTask]  WITH CHECK ADD  CONSTRAINT [FK_RoleTask_Task] FOREIGN KEY([TaskId])
REFERENCES [dbo].[Task] ([Id])
GO
ALTER TABLE [dbo].[RoleTask] CHECK CONSTRAINT [FK_RoleTask_Task]
GO
/** DATA **/

INSERT INTO [Department] ([Id], [Name]) VALUES (1, 'Housekeeping');
INSERT INTO [Department] ([Id], [Name]) VALUES (2, 'Security');
INSERT INTO [Department] ([Id], [Name]) VALUES (3, 'External Maintenance');
INSERT INTO [Department] ([Id], [Name]) VALUES (4, 'Internal Maintenance');

INSERT INTO [Role] ([Id], [Name], [DepartmentId]) VALUES (1, 'Cleaner', 1);
INSERT INTO [Role] ([Id], [Name], [DepartmentId]) VALUES (2, 'Housekeeping Supervisor', 1);
INSERT INTO [Role] ([Id], [Name], [DepartmentId]) VALUES (3, 'Toilet Cleaning Specialist', 1);
INSERT INTO [Role] ([Id], [Name], [DepartmentId]) VALUES (4, 'Security Guard', 2);
INSERT INTO [Role] ([Id], [Name], [DepartmentId]) VALUES (5, 'Electrician', 4);
INSERT INTO [Role] ([Id], [Name], [DepartmentId]) VALUES (6, 'Plumber', 4);
INSERT INTO [Role] ([Id], [Name], [DepartmentId]) VALUES (7, 'Gardener', 3);
INSERT INTO [Role] ([Id], [Name], [DepartmentId]) VALUES (8, 'Topiary Guru', 3);

INSERT INTO [Task] ([Id], [Name]) VALUES (1, 'Toilet Clean');
INSERT INTO [Task] ([Id], [Name]) VALUES (2, 'Light Out');
INSERT INTO [Task] ([Id], [Name]) VALUES (3, 'Blocked Sink');
INSERT INTO [Task] ([Id], [Name]) VALUES (4, 'Toilet Inspection');
INSERT INTO [Task] ([Id], [Name]) VALUES (5, 'Leaky Tap');
INSERT INTO [Task] ([Id], [Name]) VALUES (6, 'Bush too bushy');
INSERT INTO [Task] ([Id], [Name]) VALUES (7, 'Mop Floor');

INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (1, 1);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (2, 1);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (3, 1);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (5, 2);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (6, 3);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (2, 4);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (6, 5);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (7, 6);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (8, 6);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (1, 7);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (2, 7);
INSERT INTO [RoleTask] ([RoleId], [TaskId]) VALUES (3, 7);

1 个答案:

答案 0 :(得分:0)

我不确定我是否完全理解了您的问题,但正如评论者建议您可能对您的架构有疑问。

首先,角色组是隐藏在不同名称下的角色;基于您的架构的唯一区别是它不一定属于某个部门。但话又说你也可以说同样的角色:即使在大型公司中,也经常有一个用户/角色向多个老板报告,因此属于多个部门。

所以你真正关注的是一个群组层次结构。如果您在路上抽象事物,您将很高兴能够一次性将任务分配给多个角色。您可以合理地将角色和角色组转储到单个表中,角色以及允许将它们相互关联的role2role表:一些角色分配其他角色,但另一种方式不是真的;某些角色属于多个角色组;和角色组有多个组;它是一个定向图,其主键是(ParentId,Id),两者都引用角色(Id)。

此外,出于所有意图和目的,您的RoleTask表已经在回答您的查询。但是您仍然需要一个名为RoleGroup的新组件。如果我在您的问题评论中得到解释,则添加新任务和新的关联角色会自动导致新的角色组。这个内射属性应该暗示任务也是隐藏在不同名称下的角色。

此外,请注意,某些任务可以在多个单独的任务中分解,并且这些单独的子任务可能是多个较大任务的一部分。这也是一个导向图。

无论如何,这就是说你应该考虑将所有这些表合并在一起。为了能够轻松添加外键,您可能希望将它们分成三部分,但如果您这样做,我建议将Tasks和RoleGroup修剪为Id字段,这是主键和外键角色(Id)的关键。

出于同样的原因,您可能还想查看Department表并在那里应用相同的逻辑。可能需要一些额外的细节,例如一个ManagerId,但在一天结束时它的角色也是一个不同的名称:它的主要目的是将用户组合在一起,并且在某些情况下,某个部门内的所有用户都应该得到一些任务。它适合上述的定向图。

最后,但并非最不重要的是,值得指出的是,个别用户(未在图表中显示,但肯定存在于您的架构中)也是他们自己的角色。很可能任务是专门分配给个人而不是角色或组。此外,你永远不知道经理何时想将他的权限委托给他的秘书,因为他在月底休假。

现在,可以说,使用大量表格和它们之间的关系来管理整个混乱当然是可能的,就像你现在正在尝试做的那样。但是你也可以引入两个新表,比如Perm(如权限)和PermPerm(如权限赋值)。并使各个节点(即User,Dept,Role,Task)继承自Perm。这样做可以让您从单个表中管理整个权限图:PermPerm。

哦,如果你有一个小时,请考虑观看这段视频:The ACL is dead。它对权限管理有一些有趣的见解: