【问题标题】:Dynamic pivot with Max(Date) from pivot具有来自枢轴的 Max(Date) 的动态枢轴
【发布时间】:2016-09-13 00:45:06
【问题描述】:

我想保持一般性,所以如果可以,我宁愿不使用我的特定数据集。

我的一般示例:我有一张有很多订单的客户表。我想要一个数据透视表,显示每个客户每个月(或一般时间范围)有多少订单。假设我想添加一列来显示该客户最近订单的日期。

所以表格看起来像:

CustomerID - January - February - March - April - May - MostRecentOrder
      0001 -       2 -        3 -     1 -     1 -   1 -      2013/5/18
      0002 -       1 -        0 -     1 -     0 -   1 -      2013/5/06
      0003 -       0 -        1 -     4 -     1 -   2 -      2013/5/11
      0004 -       2 -        0 -     0 -     1 -   0 -      2013/4/28

我试图在http://sqlfiddle.com/#!6/cbbad/1 上获得一个可以工作的 sqlfiddle,但我显然比我在 Dynamic pivots 上总体上想象的要糟糕。

【问题讨论】:

    标签: sql sql-server pivot


    【解决方案1】:

    如果您想包含每个客户的最近日期,则可以使用max(orderdate) over(partition by customerId)

    select customer.CustomerID, 
      o.OrderDate,
      max(o.orderdate) over(partition by customer.customerid) mostrecentorder
    from Customers as customer
    join Orders as o 
      on customer.CustomerID = o.customerid;
    

    SQL Fiddle with Demo

    您的完整代码类似于:

    declare @start DATE = '2012-01-01';
    declare @end DATE = DATEADD(dd,-(DAY(GETDATE())-1),GETDATE());
    
    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);
    
    with months (dateList)
    AS
    (
        SELECT @start
        UNION ALL
        SELECT DATEADD(month,1,dateList)
        from months
        where DATEADD(month,1,dateList)<=@end
    )
    select dateList 
    into #tempDates
    from months
    option (maxrecursion 0);
    
    select @cols = STUFF((SELECT distinct ',' + QUOTENAME(convert(varchar(10), datelist, 120)) 
                        from #tempDates
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    set @query = '
    select *
    from
    (
      select customer.CustomerID, 
        o.OrderDate,
        max(o.orderdate) over(partition by customer.customerid) mostrecentorder
      from Customers as customer
      join Orders as o 
        on customer.CustomerID = o.customerid
    ) x
    pivot
    (
      Count(OrderDate)
      for OrderDate in ('+ @cols + ')
    )y'
    
    execute sp_executesql @query
    

    SQL Fiddle with Demo

    如果您想按月显示数据(您在上面的结果中显示),那么您可以稍微更改代码以使用DATENAME

    declare @start DATE = '2012-01-01';
    declare @end DATE = DATEADD(dd,-(DAY(GETDATE())-1),GETDATE());
    
    DECLARE @cols AS NVARCHAR(MAX),
        @query  AS NVARCHAR(MAX);
    
    with months (dateList)
    AS
    (
        SELECT @start
        UNION ALL
        SELECT DATEADD(month,1,dateList)
        from months
        where DATEADD(month,1,dateList)<=@end
    )
    select dateList 
    into #tempDates
    from months
    option (maxrecursion 0);
    
    select @cols = STUFF((SELECT ',' + QUOTENAME(mth) 
                        from
                        (
                          select datepart(month, datelist) so, datename(month, datelist) mth
                          from #tempDates
                        ) d
                        group by so, mth
                        order by so, mth
                FOR XML PATH(''), TYPE
                ).value('.', 'NVARCHAR(MAX)') 
            ,1,1,'')
    
    set @query = '
    select customerId, '+@cols+', mostrecentorder
    from
    (
      select customer.CustomerID, 
        datename(month, o.OrderDate) orderDate,
        max(o.orderdate) over(partition by customer.customerid) mostrecentorder
      from Customers as customer
      join Orders as o 
        on customer.CustomerID = o.customerid
    ) x
    pivot
    (
      Count(OrderDate)
      for OrderDate in ('+ @cols + ')
    )y'
    
    execute sp_executesql @query;
    

    SQL Fiddle with Demo。这将给出一个结果:

    | CUSTOMERID | JANUARY | FEBRUARY | MARCH | APRIL | MAY | JUNE | JULY | AUGUST | SEPTEMBER | OCTOBER | NOVEMBER | DECEMBER |            MOSTRECENTORDER |
    |------------|---------|----------|-------|-------|-----|------|------|--------|-----------|---------|----------|----------|----------------------------|
    |          3 |       1 |        1 |     1 |     1 |   1 |    0 |    0 |      0 |         0 |       0 |        0 |        0 | May, 03 2013 00:00:00+0000 |
    |          2 |       1 |        1 |     1 |     1 |   1 |    0 |    0 |      0 |         0 |       0 |        0 |        0 | May, 13 2013 00:00:00+0000 |
    |          1 |       1 |        2 |     0 |     1 |   1 |    0 |    0 |      0 |         0 |       0 |        0 |        0 | May, 23 2013 00:00:00+0000 |
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-06-26
      • 2017-09-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多