我有3个SQL表: 员工表(ID,名称等......) 关键技能表(id,技能名称) 链接表(员工ID,技能ID)
员工显然可以拥有多项关键技能,但我正试图将它们作为“员工报告”排在一行,如下所示:
第1行 - 名称,dob,关键技能1,关键技能2等.... 第2行 - 名称,dob,关键技能1,关键技能2等....
我可以使用以下方法获得以多行返回的技能:
SELECT DISTINCT kst.KeySkillName FROM KeySkillsTable
INNER JOIN KeySkillsLinkTable kslt ON kslt.EmployeeId = 2
INNER JOIN KeySkillsTable kst ON kst.Id = kslt.KeySkillsId
但是当我把它作为子查询放入更大的select时,我得到以下错误:
子查询返回的值超过1。当子查询遵循=,!=,<,< =,>,> =或子查询用作表达式时,不允许这样做。
我认为这是因为子查询返回多行,而不是我需要的多列。
任何人都可以给予任何帮助,非常感谢,提前谢谢。
答案 0 :(得分:3)
您可以使用PIVOT
执行此类转换。有两种方法,一种是静态数据透视表,用于对列的值进行硬编码,另一种是动态数据透视表,用于在运行时确定列。以下是如何根据您的情况执行此操作的示例。
Static Pivot(参见SQL Fiddle with Demo)
select *
from
(
select e.id, e.name, s.skillname, count(*) cnt
from employee e
left join emp_skill es
on e.id = es.emp_id
left join skills s
on es.skill_id = s.id
group by e.id, e.name, s.skillname
) x
pivot
(
sum(cnt)
for skillname in([skill 1], [skill 2], [skill 3])
) p
动态数据透视(参见SQL Fiddle with Demo)
DECLARE @cols AS NVARCHAR(MAX),
@query AS NVARCHAR(MAX)
select @cols = STUFF((SELECT distinct ',' + QUOTENAME(skillname)
from skills
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'')
set @query
= 'SELECT id, name,' + @cols + ' from
(
select e.id, e.name, s.skillname, count(*) cnt
from employee e
left join emp_skill es
on e.id = es.emp_id
left join skills s
on es.skill_id = s.id
group by e.id, e.name, s.skillname
) x
pivot
(
sum(cnt)
for skillname in(' + @cols + ')
) p '
execute(@query)
两个查询都会产生相同的结果。不同之处在于,首先必须编写要成为列的所有值。