【问题标题】:How to get multiple columns in Crosstab如何在交叉表中获取多个列
【发布时间】:2020-04-18 18:35:57
【问题描述】:

我想要下表中的交叉表。

交叉表应该是这样的

数据透视表似乎不能解决问题,因为一次只能使用一列。但在我们的例子中,我们正在处理 4 个不同的列。 (付费、月、年、免费) 我通过将这 4 列拆分为四个不同的数据透视表、使用临时表并最终重新组装获得的数据来解决这个问题。但这很复杂,冗长而令人困惑,总之不是很好...... 年份和月份应以升序形式显示,正如您在上面的交叉表中看到的那样。

我一直在寻找解决方案,但在任何地方都找不到相同的问题。 如果有人能给我一个简短而优雅的解决方案,我将不胜感激。

http://www.sqlfiddle.com/#!18/7216f/2 下可以看到问题定义。

谢谢!

【问题讨论】:

    标签: sql sql-server sql-server-2012 pivot


    【解决方案1】:

    您可以使用row_number() 在子查询中按日期对记录进行排名,然后使用条件聚合进行透视:

    select
        ClientId,
        max(case when rn = 1 then Payment end) Payment1,
        max(case when rn = 2 then Payment end) Payment2,
        max(case when rn = 3 then Payment end) Payment3,
        max(case when rn = 1 then [Month] end) Month1,
        max(case when rn = 2 then [Month] end) Month2,
        max(case when rn = 3 then [Month] end) Month3,
        max(case when rn = 1 then [Year] end) Year1,
        max(case when rn = 2 then [Year] end) Year2,
        max(case when rn = 3 then [Year] end) Year3,
        max(case when rn = 1 then FreeOfCharge end) FreeOfCharge1,
        max(case when rn = 2 then FreeOfCharge end) FreeOfCharge2,
        max(case when rn = 3 then FreeOfCharge end) FreeOfCharge3
    from (
        select 
            t.*,
            row_number() over(partition by ClientId order by [Year], [Month]) rn
        from mytable t
    ) t
    group by ClientId
    

    【讨论】:

    • 也是很好的解决方案。仍然必须决定我将使用哪种解决方案:) 问候
    【解决方案2】:

    您可以将表与自身连接几次,如下所示:

    with p as (
      select
        *, row_number() over(partition by clientid order by year, month) as n
      from Payment
    )
    select
      p1.clientid,
      p1.payment, p2.payment, p3.payment,
      p1.month, p2.month, p3.month,
      p1.year, p2.year, p3.year,
      p1.freeofcharge, p2.freeofcharge, p3.freeofcharge
    from p p1
    left join p p2 on p2.clientid = p1.clientid and p2.n = 2
    left join p p3 on p3.clientid = p1.clientid and p3.n = 3
    where p1.n = 1
    

    Fiddle

    【讨论】:

    • 我得到了我“梦寐以求”的“简短、优雅”的解决方案 :) 幸好你和 Stackoverflow 都在这里!非常感谢你,新年快乐。附:开头必须是分号,然后是完美的。
    • 使用此解决方案,我无法将结果插入临时表。所以我使用了 GMB 的解决方案,因为使用他的解决方案很容易将结果插入到临时表中。
    • 不用担心。如果您需要将 CTE 与插入相结合,只需在主要(最后一个)SELECT 之前添加 INSERT 子句。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多