给出以下表格/关系
编辑:如果使用下面的SQL填充,则应返回此....
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实现此目的。
任何提示或提示表示赞赏。
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);
答案 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。它对权限管理有一些有趣的见解: