简体   繁体   English

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

[英]SQL Server query for grouping row as column and getting corresponding designation

I have 2 tables in SQL Server: 我在SQL Server中有2个表:

Table 1 : Department 表1: 部门

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

Table 2 : Designation 表2: 名称

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

I want the following output which takes department as column heading and group designation under the corresponding department column, 我想要以下输出,将部门作为列标题,并在相应的部门列下指定组,

  Software Development     Testing     Customization
        TL                 TestEngg        SE
        PL             

I tried with the below query but Im able to get only the Id's 我尝试使用以下查询,但我只能获取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)

I think PIVOT keyword is what you should use here. 我认为PIVOT关键字是您应该在这里使用的关键字。 PIVOT can be used to transform datasets such that columns become rows. PIVOT可用于转换数据集,以使列成为行。

No need to construct dynamic queries 无需构造动态查询

Take a look at this article: http://archive.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=PIVOTData 看一下这篇文章: http : //archive.msdn.microsoft.com/SQLExamples/Wiki/View.aspx?title=PIVOTData

More info: http://msdn.microsoft.com/en-us/library/ms177410(v=sql.105).aspx 详细信息: http : //msdn.microsoft.com/zh-cn/library/ms177410(v=sql.105).aspx

Your code was so very close. 您的代码非常接近。 My suggestion when working with PIVOT especially a dynamic version is to write the static version first, then convert it to dynamic sql. 在使用PIVOT尤其是动态版本时,我的建议是先编写静态版本,然后将其转换为动态sql。

The static version, where you hard-code values is like this: 静态版本中,您可以对值进行硬编码,如下所示:

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

See SQL Fiddle with Demo . 请参阅带有演示的SQL Fiddle The static version allows you to be sure that the syntax is correct and all values, columns etc are in the right places. 静态版本使您可以确保语法正确,并且所有值,列等均位于正确的位置。

Then once you have the syntax it is easy to convert to the dynamic SQL version: 然后,一旦有了语法,就可以轻松转换为动态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)

See SQL Fiddle with Demo 参见带有演示的SQL Fiddle

Both give the result: 两者都给出结果:

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

You will notice that I added the line row_number() over(partition by s.deptid order by s.desigid) rn to the SELECT statement. 您会注意到,我在SELECT语句中添加了row_number() over(partition by s.deptid order by s.desigid) rn行。 This allows you to return more than one Desig Name for each Dept Name , without this you will only return one value. 这使您可以返回多个Desig Name为每个Dept Name ,如果没有这个,你将只返回一个值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM