选择行到列中并在列

时间:2015-09-11 15:36:06

标签: sql sql-server-2008 pivot

尝试获得如下输出:

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

这显示了一个人的角色。一个人可以有0或N个角色。当一个人有角色时,我会显示一个标志,如'1'。

实际上我有两个代码块:

块#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 |

欢迎任何混合两个块以显示最高输出的帮助。感谢。

2 个答案:

答案 0 :(得分:3)

没有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

答案 1 :(得分:1)

你可以试试这个。

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