【问题标题】:Select rows into columns and show a flag in the column将行选择为列并在列中显示标志
【发布时间】:2015-09-11 15:36:05
【问题描述】:

试图获得如下输出:

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

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

【问题讨论】:

  • AvailableRoles 是静态表吗?如果没有,您可能需要动态 sql
  • 好! AvailableRoles 不是静态的。当然,我将来会向它添加更多行。感谢您的提问。

标签: sql sql-server-2008 pivot


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    你可以试试这个。

    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

    【讨论】:

    • 需要COALESCE(field,0)SELECT 中的每个字段,或者使用交叉创建所有可能的技能/人员列表,然后再进行旋转,如果您想要所有 1 和空白而不是NULLs
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-07-11
    • 1970-01-01
    相关资源
    最近更新 更多