1

我在 SQL Server 中有 2 个表:

表一:部门

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

2 回答 2

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

于 2012-12-14T07:41:07.340 回答
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

两者都给出结果:

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

你会注意到我row_number() over(partition by s.deptid order by s.desigid) rnSELECT语句中添加了这一行。这允许您Desig Name为每个Dept Name返回多个值,否则您将只返回一个值。

于 2012-12-14T10:17:05.763 回答