0

我无法弄清楚如何将行设置为 cols 或使用 pivot 来动态生成 cols。有 3 个表 - tblEmp、tblLeaveType 和 tblEmpLeaves。现在的结果集是

EmpId Name Type Days
--------------------
 1    john  al   5
 1    john  cl   2
 2    smith al   3
 3    jack  sl   4

我想按照以下方式获得它。

EmpId Name    al     cl     sl
--------------------------------
 1    john    5      2     null
 2    smith   3     null   null
 3    jack    null  null   4

休假类型可以动态添加。请在此处查看小提琴 - http://sqlfiddle.com/#!3/6ad02e/1 使用 sql server 2008, c#

4

1 回答 1

2

如果您只想使用 SQL 获得最终结果,那么您可以实现 PIVOT 函数。在尝试编写动态 SQL 版本之前,您应该始终先编写硬编码版本,以便您可以正确地获得基本逻辑。

types如果您需要转换为列的数量有限,那么您可以使用:

select id, name, al, cl, sl
from
(
  select e.id, e.name, lt.type, l.days 
  from tblEmp e
  left outer join tblEmpLeaves l 
    on e.id = l.empId
  left outer join tblLeaveType lt 
    on l.leaveId = lt.Id
) d
pivot
(
  max(days)
  for type in (al, cl, sl)
) piv
order by id;

请参阅SQL Fiddle with Demo

但是,如果您要获得未知数量的值,则必须使用动态 SQL,并且将代码放在存储过程中:

DECLARE @cols AS NVARCHAR(MAX),
    @query  AS NVARCHAR(MAX)

select @cols = STUFF((SELECT distinct ',' + QUOTENAME(type) 
                    from tblLeaveType
            FOR XML PATH(''), TYPE
            ).value('.', 'NVARCHAR(MAX)') 
        ,1,1,'')

set @query = 'SELECT id, name,' + @cols + ' 
            from 
            (
              select e.id, e.name, lt.type, l.days 
              from tblEmp e
              left outer join tblEmpLeaves l 
                on e.id = l.empId
              left outer join tblLeaveType lt 
                on l.leaveId = lt.Id
            ) x
            pivot 
            (
                max(days)
                for type in (' + @cols + ')
            ) p 
            order by id'

execute sp_executesql @query;

请参阅SQL Fiddle with Demo。他们都给你结果:

| ID |  NAME |     AL |     CL |     SL |
|----|-------|--------|--------|--------|
|  1 |  john |      5 |      2 | (null) |
|  2 | smith |      3 | (null) | (null) |
|  3 |  jack | (null) | (null) |      4 |
于 2013-11-11T12:50:08.413 回答