SQL Server查询将行分组为列并获得相应的指定

时间:2012-12-14 05:38:32

标签: sql sql-server tsql sql-server-2008-r2 pivot

我在SQL Server中有两个表:

表1:部门

DeptId   Dept Name
------------------
1        Software Development
2        Testing
3        Customization

表2:指定

DesigId  Desig Name  DeptId
---------------------------
 1        TL          1
 2        PL          1
 3        TestEngg    2
 4        SE          3

我想要以下输出,它将部门作为相应部门列下的列标题和组指定,

  Software Development     Testing     Customization
        TL                 TestEngg        SE
        PL             

我尝试使用以下查询,但我只能获得Id的

 DECLARE @deptcols AS VARCHAR(MAX);
 DECLARE @querystr  AS VARCHAR(MAX);


select @deptcols = STUFF((SELECT distinct ',' + QUOTENAME(Dept_Id) 
              FROM Designation 
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')

 set @querystr = 'SELECT ' + @deptcols + ' from 
         (
             select Desig_Name, Dept_Id,Desig_Id
             from Designation
        ) p
        pivot 
        (
           count(Desig_Id) FOR Dept_Id in (' + @deptcols + ')
        ) pv '
 execute(@querystr)

2 个答案:

答案 0 :(得分:0)

我认为PIVOT关键字是你应该在这里使用的。 PIVOT可用于转换数据集,使列成为行。

无需构建动态查询

看一下这篇文章:http://archive.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=PIVOTData

更多信息:http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx

答案 1 :(得分:0)

您的代码非常接近。在使用PIVOT尤其是动态版本时,我的建议是首先编写静态版本,然后将其转换为动态sql。

静态版本,您对值进行硬编码是这样的:

SELECT [Software Development], [Testing], [Customization]
from 
(
   select d.[Dept Name], 
      s.[Desig Name],
      row_number() over(partition by s.deptid order by s.desigid) rn
   from Designation s
   left join department d
      on s.[DeptId] = d.[DeptId]
) p
pivot 
(
  max([Desig Name]) 
  FOR [Dept Name] in ([Software Development], [Testing], [Customization])
) pv

SQL Fiddle with Demo。静态版本允许您确保语法正确并且所有值,列等都在正确的位置。

然后,一旦掌握了语法,就很容易转换为动态SQL版本:

DECLARE @deptcols AS VARCHAR(MAX)
DECLARE @querystr  AS VARCHAR(MAX)

select @deptcols = STUFF((SELECT  ',' + QUOTENAME([Dept Name]) 
              FROM Department 
              GROUP BY [Dept Name], DeptId
              ORDER BY DeptId
        FOR XML PATH(''), TYPE
        ).value('.', 'NVARCHAR(MAX)') 
    ,1,1,'')

set @querystr = 
      'SELECT ' + @deptcols + ' from 
         (
            select d.[Dept Name], 
                s.[Desig Name],
              row_number() over(partition by s.deptid order by s.desigid) rn
            from Designation s
            left join department d
               on s.[DeptId] = d.[DeptId]
        ) p
        pivot 
        (
           max([Desig Name]) 
           FOR [Dept Name] in (' + @deptcols + ')
        ) pv '

execute(@querystr)

请参阅SQL Fiddle with Demo

两者都给出结果:

| SOFTWARE DEVELOPMENT |  TESTING | CUSTOMIZATION |
---------------------------------------------------
|                   TL | TestEngg |            SE |
|                   PL |   (null) |        (null) |

您会注意到我在row_number() over(partition by s.deptid order by s.desigid) rn语句中添加了行SELECT。这样,您就可以为每个Desig Name返回多个Dept Name,如果没有这个,您只会返回一个值。