I have 2 tables in SQL Server:
Table 1 : Department
DeptId Dept Name
------------------
1 Software Development
2 Testing
3 Customization
Table 2 : Designation
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
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 can be used to transform datasets such that columns become rows.
No need to construct dynamic queries
Take a look at this article: 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
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.
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 . 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:
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)
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. This allows you to return more than one Desig Name
for each Dept Name
, without this you will only return one value.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.