我在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)
答案 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)
两者都给出结果:
| 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
,如果没有这个,您只会返回一个值。