我有一个Employee表,当我按照SQL执行查询时给出以下结果:
Select ID, Role as "Role Name", Employee as "Employee Name"
from employee
现在,我想按照下图转换上面的查询结果。我使用了最大和最小的Pivot&然后做了工会,但它只提供了与角色名称相对应的两个员工姓名。我需要得到如下结果。有什么建议吗?
答案 0 :(得分:3)
select
id,
case when [Role Name] = 'Consultant'
then [Employee Name] else null
end as Consultant,
case when [Role Name] = 'Manager'
then [Employee Name] else null
end as Manager
from
employee
如果您有其他角色,可以添加更多案例陈述
使用Pivot,
select
id,
Consultant,
Manager
from
( select
id,
[Role Name],
[Employee Name],
row_number() over( partition by id order by id) as rn
from
employee
) src
pivot
( max([Employee Name]) for [Role Name] in (Consultant,Manager) ) as pvt ;
更新
如果您有多个角色或非固定数量的角色,这可能不是一个好的解决方案。
一种方法是dynamic pivot
答案 1 :(得分:1)
`Jophab的方法是一种非常好的方法。如果您正在学习SQL,请考虑以下另一种方法:
select id, employeename as consultant, null as manager
from employee
where rolename = 'Consultant'
union all
select id, null as employeename as manager
from employee
where rolename = 'Manager';
这需要两次扫描employee
表 - 这对于小表来说非常简单。
编辑:
另一种不需要大量case
表达式的方法使用join
:
select e.id, v.*
from employee e join
(values ('consultant', employeename, null),
('manager', null, employeename)
) v(rolename, consultant, manager)
on e.rolename = v.rolename;
但是,您必须为null
中的每一行键入一堆values()
个。
答案 2 :(得分:1)
如果您拥有的角色数量可以改变,这是一个未来证明的答案;因此你需要改变你的SQL。这避免了这种需要,但是(像Gordan当前的答案一样)需要对表进行2次扫描:
CREATE TABLE Employee (ID int, [Role] varchar(10), Employee varchar(15));
INSERT INTO Employee
VALUES (1, 'Manager','Steve'),
(2, 'Consultant','Jayne');
GO
--Hard coded SQL solution
SELECT ID,
CASE [Role] WHEN 'Manager' THEN Employee END AS Manager,
CASE [Role] WHEN 'Consultant' THEN Employee END AS Consultant
FROM Employee;
GO
--Now, let's add a another role, and try the SQL again:
INSERT INTO Employee
VALUES (3, 'Director','Sally');
SELECT ID,
CASE [Role] WHEN 'Manager' THEN Employee END AS Manager,
CASE [Role] WHEN 'Consultant' THEN Employee END AS Consultant
FROM Employee;
--Unsurprisingly, Sally doesn't appear, but a "blank" row does
GO
--Dynamic SQL solution:
DECLARE @SQL nvarchar(MAX);
SET @SQL = N'SELECT ID,' +NCHAR(10) +
STUFF((SELECT DISTINCT N',' + NCHAR(10) +
N' CASE [Role] WHEN ' + QUOTENAME([Role],N'''') + N' THEN Employee END AS ' + QUOTENAME([Role])
FROM Employee
FOR XML PATH(N'')),1,2,N'') + NCHAR(10) +
N'FROM Employee;';
PRINT @SQL; --your best friend
EXEC sp_executesql @SQL;
GO
DROP TABLE Employee;