Select 行放入列中并在列中显示标志

Select rows into columns and show a flag in the column

正在尝试获得如下所示的输出:

| UserFullName | JAVA   | DOTNET | C      | HTML5  |
|--------------|--------|--------|--------|--------|
|     Anne San |        |        |        |        |
|   John Khruf |      1 |      1 |        |      1 |
|    Mary Jane |      1 |        |        |      1 |
|  George Mich |        |        |        |        |

This shows the roles of a person. A person could have 0 or N roles. When a person has a role, I am showing a flag, like '1'.


实际上我有2个代码块:

第 1 块: 每个人生成超过 1 行的表格和简单输出。

SQL Fiddle

MS SQL Server 2008 架构设置:

CREATE TABLE AvailableRoles 
(
  id int identity primary key, 
  CodeID varchar(5), 
  Description varchar(500), 
);

INSERT INTO AvailableRoles
(CodeID, Description)
VALUES
('1', 'JAVA'),
('2', 'DOTNET'),
('3', 'C'),
('4', 'HTML5');

CREATE TABLE PersonalRoles 
(
  id int identity primary key, 
  UserID varchar(100), 
  RoleID varchar(5), 
);

INSERT INTO PersonalRoles
(UserID, RoleID)
VALUES
('John.Khruf', '1'),
('John.Khruf', '2'),
('Mary.Jane', '1'),
('Mary.Jane', '4'),
('John.Khruf', '4');


CREATE TABLE Users 
(
  UserID varchar(20), 
  EmployeeType varchar(1),
  EmployeeStatus varchar(1),
  UserFullName varchar(500), 
);

INSERT INTO Users
(UserID, EmployeeType, EmployeeStatus, UserFullName)
VALUES
('John.Khruf', 'E', 'A', 'John Khruf'),
('Mary.Jane', 'E', 'A', 'Mary Jane'),
('Anne.San', 'E', 'A', 'Anne San'),
('George.Mich', 'T', 'A', 'George Mich');

查询 1:

SELECT
  A.UserFullName,
  B.RoleID
FROM
  Users A
LEFT JOIN PersonalRoles B ON B.UserID = A.UserID
WHERE
  A.EmployeeStatus = 'A'
ORDER BY
  A.EmployeeType ASC,
  A.UserFullName ASC

结果:

| UserFullName | RoleID |
|--------------|--------|
|     Anne San | (null) |
|   John Khruf |      1 |
|   John Khruf |      2 |
|   John Khruf |      4 |
|    Mary Jane |      1 |
|    Mary Jane |      4 |
|  George Mich | (null) |

块 #2: 尝试将行转换为列以用于最终结果

SQL Fiddle

MS SQL Server 2008 架构设置:

CREATE TABLE AvailableRoles 
(
  id int identity primary key, 
  CodeID varchar(5), 
  Description varchar(500), 
);

INSERT INTO AvailableRoles
(CodeID, Description)
VALUES
('1', 'JAVA'),
('2', 'DOTNET'),
('3', 'C'),
('4', 'HTML5');

查询 1:

SELECT
  *
FROM
(
  SELECT CodeID, Description
  FROM AvailableRoles
) d
PIVOT
(
  MAX(CodeID)
  FOR Description IN (Java, DOTNET, C, HTML5)
) piv

结果:

| Java   | DOTNET | C     | HTML5  |
|--------|--------|-------|--------|
|      1 |      2 |     3 |      4 |

欢迎任何帮助混合两个块以显示顶部输出的帮助。谢谢。

你可以试试这个。

SELECT  *
FROM
(
select u.userfullname,
case when p.roleid is not null then 1 end as roleid,
a.description
from users u 
left join personalroles p
on p.userid = u.userid
left join availableroles a 
on a.codeid = p.roleid
) d
PIVOT
(
  MAX(roleID)
  FOR Description IN (Java, DOTNET, C, HTML5)
) piv

Fiddle

另一个没有 PIVOT 运算符的选项是:

select u.UserFullName,
       max(case when a.CodeID='1' then '1' else '' end) JAVA,
       max(case when a.CodeID='2' then '1' else '' end) DOTNET,
       max(case when a.CodeID='3' then '1' else '' end) C,
       max(case when a.CodeID='4' then '1' else '' end) HTML5
  from
   Users u 
   LEFT JOIN PersonalRoles p on (u.UserID = p.UserID)
   LEFT JOIN AvailableRoles a on (p.RoleID = a.CodeID)
group by u.UserFullName
order by u.UserFullName

SQLFiddle: http://sqlfiddle.com/#!3/630c3/19