使用多对多关系生成像pivot一样的列

时间:2015-07-30 20:49:09

标签: sql-server

我有三个名为Project,ProjectMember和User的表,其中ProjectMember是一个联结表,并且有一个MemberType列(有效值为0,1和2)。我需要返回所有项目,结果集必须具有MemberType等于0和1(每列在一列上)的用户的名称。

以下是MemberType的规则:

  • 每个项目必须只有一个UserType = 0的用户
  • 每个项目必须有零个或一个UserType = 1
  • 的用户
  • 每个项目可以有零个或多个具有MemberType = 2的用户(在此查询中不会返回它们)

如何防止同一个项目出现多行?

这是一个用于创建像我一样的表的示例脚本:

CREATE TABLE Project (
  Id int,
  Name VARCHAR(50),
  CONSTRAINT PK_Project PRIMARY KEY (Id));


CREATE TABLE [User] (
  Id int,
  Name VARCHAR(50),
  CONSTRAINT PK_User PRIMARY KEY (Id));

CREATE TABLE ProjectMember (
  Project_Id int,
  User_Id int, 
  MemberType tinyint,
  CONSTRAINT PK_ProjectMember PRIMARY KEY(Project_Id, User_Id),
  CONSTRAINT FK_ProjectMember_Project FOREIGN KEY(Project_Id) REFERENCES Project(Id),
  CONSTRAINT FK_ProjectMember_User FOREIGN KEY(User_Id) REFERENCES [User](Id));



 INSERT INTO Project(Id, Name) VALUES(1, 'Project 1');
 INSERT INTO Project(Id, Name) VALUES(2, 'Project 2');
 INSERT INTO Project(Id, Name) VALUES(3, 'Project 3');
 INSERT INTO Project(Id, Name) VALUES(4, 'Project 4');


 INSERT INTO [User](Id, Name) VALUES(1, 'User 1');
 INSERT INTO [User](Id, Name) VALUES(2, 'User 2');
 INSERT INTO [User](Id, Name) VALUES(3, 'User 3');
 INSERT INTO [User](Id, Name) VALUES(4, 'User 4');
 INSERT INTO [User](Id, Name) VALUES(5, 'User 5');
 INSERT INTO [User](Id, Name) VALUES(6, 'User 6');

 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(1, 1, 0);
 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(1, 2, 1);
 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(1, 3, 2);
 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(1, 4, 2);
 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(1, 5, 2);
 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(3, 6, 0);
 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(3, 5, 1);
 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(4, 3, 0);
 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(4, 4, 1);
 INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(4, 5, 2);

这就是现在的查询方式:

SELECT 
  P.Id, P.Name, Type0.Name as UserType0, Type1.Name as UserType1 
FROM 
Project as P
  LEFT JOIN ProjectMember as PM ON P.Id = PM.Project_Id
  LEFT JOIN [User] as Type0 ON PM.User_Id = Type0.Id AND PM.MemberType = 0
  LEFT JOIN [User] as Type1 ON PM.User_Id = Type1.Id AND PM.MemberType = 1

我需要我的结果集,每个项目只有一行。我尝试将ProjectMember和User(Type0)之间的JOIN更改为INNER JOIN但是它导致了Type1的JOIN问题。

2 个答案:

答案 0 :(得分:0)

使用[1, 2, 5]

PIVOT

答案 1 :(得分:0)

根据我的理解,这是我的尝试:

select id,
       ProjectName,
       [0] as Type0,
       [1] as Type1
from 
(SELECT 
  P.Id, P.Name as projectname, u.Name as username,pm.membertype  
FROM 
Project as P
  LEFT JOIN ProjectMember as PM ON P.Id = PM.Project_Id
  LEFT JOIN [User] as u ON PM.User_Id = u.Id 
 ) t
 PIVOT
 (
   MAX(username) FOR membertype in ([0],[1])
 ) p;

SQL Fiddle Demo