【问题标题】:How to pivot values from rows to column based on value from related column如何根据相关列的值将值从行旋转到列
【发布时间】:2023-03-23 00:25:01
【问题描述】:

我正在尝试基于 3 个值对一组数据进行透视,以便每一行代表与每个 ID 相关的所有配置文件 URL,每列与配置文件代码相关

这个问题与我想要达到的目标非常相似,但是它没有根据另一个值对正在旋转的列进行分组:Pivot values on column based on grouped columns in SQL

所以给出下面的示例表:

Id        ProfileCode  ProfileURL  
-------------------------------------------------------
7ADC7368  IA           http://www.domainIA.com/profile1
5C627D6F  IA           http://www.domainIA.com/profile2
5C627D6F  AG           http://www.domainAG.com/profile1
5C627D6F  AF           http://www.domainAF.com/profile1
664B4AE9  IA           http://www.domainIA.com/profile3
664B4AE9  AF           http://www.domainAF.com/profile2

我希望将其转换成下表:

Id        IA                                AG                                AF
-------------------------------------------------------------------------------------------------------------
7ADC7368  http://www.domainIA.com/profile1  null                              null
5C627D6F  http://www.domainIA.com/profile2  http://www.domainAG.com/profile1  http://www.domainAF.com/profile1
664B4AE9  http://www.domainIA.com/profile3  null                              http://www.domainAF.com/profile2

这是我一直在尝试使用的代码,但我找不到将枢轴与配置文件 URL 与其关联的配置文件代码之间的关联相关联的方法。

declare @tmp TABLE (Id NVARCHAR(15), ProfileCode NVARCHAR(2), ProfileURL NVARCHAR(50))

insert into @tmp (Id, ProfileCode, ProfileURL)
values  ('7ADC7368', 'IA', 'http://www.domainIA.com/profile1'),
        ('5C627D6F', 'IA', 'http://www.domainIA.com/profile2'),
        ('5C627D6F', 'AG', 'http://www.domainAG.com/profile1'),
        ('5C627D6F', 'AF', 'http://www.domainAF.com/profile1'),
        ('664B4AE9', 'IA', 'http://www.domainIA.com/profile3'),
        ('664B4AE9', 'AF', 'http://www.domainAF.com/profile2')

select 
     pvt.id,
    CASE
        WHEN ProfileCode = 'IA' THEN ProfileURL 
    END AS 'IA',
    CASE
        WHEN ProfileCode = 'AF' THEN ProfileURL 
    END AS 'AF',
    CASE
        WHEN ProfileCode = 'AG' THEN ProfileURL
    END AS 'AG'
from (  
    select 
         Id, ProfileCode, ProfileURL
        ,ROW_NUMBER() over(partition by ProfileCode order by ProfileURL) as RowNum
from 
    @tmp
) a
pivot (MAX(ProfileCode) for RowNum in ('IA', 'AF', 'AG') as pvt

对于我正在努力实现的目标,我将不胜感激。

【问题讨论】:

    标签: sql sql-server pivot aggregation


    【解决方案1】:

    只使用条件聚合:

    SELECT id,
           MAX(CASE WHEN ProfileCode = 'IA' THEN ProfileURL END) AS IA,
           MAX(CASE WHEN ProfileCode = 'AF' THEN ProfileURL END) AS AF,
           MAX(CASE WHEN ProfileCode = 'AG' THEN ProfileURL END) AS AG
    FROM @tmp t
    GROUP BY id;
    

    如果给定 id 有多个相同的代码并且你希望结果在不同的行上,你只需要ROW_NUMBER()。您的示例数据和当前逻辑表明情况并非如此。

    【讨论】:

    • 哇,非常感谢@gordon,这比我做的简单多了。很明显我今天盯着代码太久了!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    • 2021-12-25
    相关资源
    最近更新 更多