I have two tables: customerTable
and orderTable
that are shown below. I need to generate order
column dynamically.
CustomerTable
custId CustName
01 Suresh
02 Ramesh
OrderTable
custId OrderId
01 011
01 012
need output as like :
custId Order1 Order2
01 011 012
Here if order is multiple times for each customer then columns will be added dynamically.
If custId = 01 has 011,012,013,014...... has many order then table will be like
custId order1 order2 order3 order4 order5 order6 ...... many oder N columns
01 011 012 013 014 015 06 ....... 0N..
What you are looking for is called pivoting. See the documentation .
A simple example taken from the link above:
USE AdventureWorks2008R2;
GO
SELECT
DaysToManufacture,
AVG(StandardCost) AS AverageCost
FROM Production.Product
GROUP BY DaysToManufacture;
Results in:
DaysToManufacture | AverageCost
----------------------------------------
0 | 5.0885
1 | 223.88
2 | 359.1082
4 | 949.4105
These are rows in the source table grouped, no pivoting done yet. By pivoting, you turn the values of the rows in column #1 into columns, and the values of the rows in column #2 get 'rotated' and appear as one row. The SQL to do that is the following:
-- Pivot table with one row and five columns
SELECT
'AverageCost' AS Cost_Sorted_By_Production_Days,
[0],
[1],
[2],
[3],
[4]
FROM
(
SELECT
DaysToManufacture,
StandardCost
FROM
Production.Product
) AS SourceTable
PIVOT
(
AVG(StandardCost)
FOR DaysToManufacture IN
(
[0],
[1],
[2],
[3],
[4]
)
) AS PivotTable;
This results in output such as:
Cost_Sorted_By_Production_Days | 0 | 1 | 2 | 3 | 4
-----------------------------------------------------------------------------
AverageCost | 5.0885 | 223.88 | 359.1082 | NULL | 949.4105
Do this dynamically like this:
declare @sql as nvarchar(max)
declare @cols as nvarchar(max)
set @cols = STUFF((SELECT distinct ',' + QUOTENAME(c.OrderId)
FROM OrderTable c
order by 1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set @sql = STUFF((SELECT ',' + QUOTENAME(OrderId) + ' as Order' + convert(varchar,row_number() over (order by OrderId))
from (
select distinct OrderId
FROM OrderTable
) t
order by 1
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'');
set @sql = 'SELECT custId, ' + @sql + ' from
(
select *
from OrderTable
) x
pivot
(
max(OrderId)
for OrderId in (' + @cols + ')
) p '
exec(@sql)
Produces:
To be noted here is that, it works correctly for one custId as the columns are aligned based on the the OrderId in the pivoted result.
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.