如何根据sql

时间:2017-01-21 09:59:40

标签: sql sql-server pivot

我有两个表格:customerTableorderTable,如下所示。我需要动态生成order列。

CustomerTable

custId CustName
01     Suresh
02     Ramesh

OrderTable

custId  OrderId 
01      011
01      012

需要输出如下:

custId Order1 Order2
01     011    012

如果每个客户的订单多次,则会动态添加列。

如果custId = 01有011,012,013,014 ......有很多订单那么表就像

custId order1  order2 order3 order4 order5 order6 ...... many oder N columns 
01     011       012   013   014    015    06     ....... 0N..   

2 个答案:

答案 0 :(得分:1)

您正在寻找的是旋转。请参阅documentation

从上面的链接中获取的一个简单示例:

USE AdventureWorks2008R2;
GO
SELECT
    DaysToManufacture,
    AVG(StandardCost) AS AverageCost
FROM Production.Product
GROUP BY DaysToManufacture;

结果:

DaysToManufacture | AverageCost
----------------------------------------
0                 | 5.0885
1                 | 223.88
2                 | 359.1082
4                 | 949.4105

这些是源表中的行分组,尚未完成透视。通过旋转,您可以将第1列中的行的值转换为列,并将第2列中的行的值“旋转”并显示为一行。执行此操作的SQL如下:

-- 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;

这导致输出如:

Cost_Sorted_By_Production_Days | 0      | 1      | 2        | 3    | 4
-----------------------------------------------------------------------------
AverageCost                    | 5.0885 | 223.88 | 359.1082 | NULL | 949.4105

答案 1 :(得分:0)

动态执行此操作:

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)

产地:

enter image description here

这里要注意的是,它适用于一个custId,因为列是根据透视结果中的OrderId对齐的。