2015-07-31 3 views
0

Я следующая структура на SQLFiddle, которая была создана другими людьми, которые помогли мне (Using two columns in a PIVOT):Как добавить фильтр, чтобы найти весь проект с конкретным пользователем

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


CREATE TABLE [User] (
    Id int, 
    Name VARCHAR(50), 
    Register int, 
    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 Project(Id, Name) VALUES(5, 'Project 5'); 
INSERT INTO Project(Id, Name) VALUES(6, 'Project 6'); 
INSERT INTO Project(Id, Name) VALUES(7, 'Project 7'); 


INSERT INTO [User](Id, Name, Register) VALUES(1, 'User 1', 23498374); 
INSERT INTO [User](Id, Name, Register) VALUES(2, 'User 2', 96849887); 
INSERT INTO [User](Id, Name, Register) VALUES(3, 'User 3', 6546884); 
INSERT INTO [User](Id, Name, Register) VALUES(4, 'User 4', 8489848); 
INSERT INTO [User](Id, Name, Register) VALUES(5, 'User 5', 4684854); 
INSERT INTO [User](Id, Name, Register) VALUES(6, 'User 6', 4849888); 
INSERT INTO [User](Id, Name, Register) VALUES(7, 'User 7', 84884446); 
INSERT INTO [User](Id, Name, Register) VALUES(8, 'User 8', 77554454); 
INSERT INTO [User](Id, Name, Register) VALUES(9, 'User 9', 77853997); 

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); 

INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(5, 7, 0); 

INSERT INTO ProjectMember(Project_Id, User_Id, MemberType) VALUES(6, 8, 1); 

У меня есть новое требование от моего клиент. Ему нужен фильтр, чтобы возвращать все проекты, у которых есть MemberType = 2 и определенный User.Id, но возвращаемые значения не обязательно должны включать эти значения.

Пример:

С этим SQL заявления:

SELECT 
    ProjectID    = P.Id, 
    ProjectName   = P.Name, 
    [UserType0 (Name)]  = MAX(CASE WHEN MemberType = 0 THEN u.Name END), 
    [UserType0 (Register)] = MAX(CASE WHEN MemberType = 0 THEN Register END), 
    [UserType1 (Name)]  = MAX(CASE WHEN MemberType = 1 THEN u.Name END), 
    (CASE WHEN MemberType = 2 THEN u.Name END) as [UserType2] 
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 
GROUP BY P.Id, P.Name, PM.MemberType, U.Name 

Я получаю следующее значение:

| ProjectID | ProjectName | UserType0 (Name) | UserType0 (Register) | UserType1 (Name) | UserType2 | 
|-----------|-------------|------------------|----------------------|------------------|-----------| 
|   1 | Project 1 |   User 1 |    23498374 |   (null) | (null) | 
|   1 | Project 1 |   (null) |    (null) |   User 2 | (null) | 
|   1 | Project 1 |   (null) |    (null) |   (null) | User 3 | 
|   1 | Project 1 |   (null) |    (null) |   (null) | User 4 | 
|   1 | Project 1 |   (null) |    (null) |   (null) | User 5 | 
|   2 | Project 2 |   (null) |    (null) |   (null) | (null) | 
|   3 | Project 3 |   User 6 |    4849888 |   (null) | (null) | 
|   3 | Project 3 |   (null) |    (null) |   User 5 | (null) | 
|   4 | Project 4 |   User 3 |    6546884 |   (null) | (null) | 
|   4 | Project 4 |   (null) |    (null) |   User 4 | (null) | 
|   4 | Project 4 |   (null) |    (null) |   (null) | User 5 | 
|   5 | Project 5 |   User 7 |    84884446 |   (null) | (null) | 
|   6 | Project 6 |   (null) |    (null) |   User 8 | (null) | 
|   7 | Project 7 |   (null) |    (null) |   (null) | (null) |

Но что мне нужно, чтобы вернуть одну строку для каждого проекта, который содержит пользователь с определенным идентификатором и MemberType = 2. Как добавить этот фильтр без изменения результатов, указанных на Using two columns in a PIVOT?

+0

В вашем проекте Project 1 есть несколько пользователей с 'MemberType = 2'. Какая из них правильная? – FutbolFan

+0

Это поддерживаемый прецедент. Проект должен иметь один член с MemberType = 0, ноль или один член с MemberType = 1 и любое количество членов с MemberType = 2. –

+0

Но вы хотите вернуть только одну строку для каждого проекта. Мне интересно, как это сделать, если у вас несколько пользователей привязаны к проекту с помощью 'MemberType = 2'? Если вы не используете min или max. – FutbolFan

ответ

0

Вот код, который я отправил в комментарии выше:

DECLARE @USerId int; 
SET @UserId = NULL; 

SELECT 
    ProjectID    = P.Id, 
    ProjectName   = P.Name, 
    [UserType0 (Name)]  = MAX(CASE WHEN MemberType = 0 THEN u.Name END), 
    [UserType0 (Register)] = MAX(CASE WHEN MemberType = 0 THEN Register END), 
    [UserType1 (Name)]  = MAX(CASE WHEN MemberType = 1 THEN u.Name END) 

FROM 
(SELECT Proj.* 
FROM Project AS Proj 
LEFT JOIN ProjectMember AS Member ON Proj.Id = Member.Project_Id 
            AND Member.MemberType = 2 
WHERE Member.User_Id = COALESCE(@UserId,Member.User_Id) 
--changed this to use coalesce      
) AS P 
LEFT JOIN ProjectMember AS PM ON P.Id = PM.Project_Id 
LEFT JOIN [User] AS U ON PM.User_Id = U.Id 
GROUP BY P.Id, P.Name; 

Надеется, что это помогает!

Смежные вопросы