【问题标题】:SQL Server query for grouping row as column and getting corresponding designation用于将行分组为列并获取相应名称的 SQL Server 查询
【发布时间】:2012-12-14 05:38:32
【问题描述】:

我在 SQL Server 中有 2 个表:

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

【问题讨论】:

  • 我使用的是 SQL Server 2008 R2
  • What have you tried? - 如果您向我们展示您自己的一些努力,我们将很乐意为您提供帮助 - 但我们不只是为您编写整个代码......

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


【解决方案1】:

您的代码非常接近。在使用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) |

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

【讨论】:

  • 感谢您的帮助。现在我才知道问题出在哪里......它按照我的要求工作
【解决方案2】:

我认为 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-09
    相关资源
    最近更新 更多