根据值将SQL列拆分为多个列

时间:2018-06-18 14:09:47

标签: sql-server sql-server-2017

我有一张如下表

Opp_ID     Role_Name     Role_User_Name
---------------------------------------
1          Lead          Person_one
1          Developer     Person_two
1          Developer     Person_three
1          Owner         Person_four
1          Developer     Person_five

我现在需要根据值将Role_Name列拆分为3个不同的列。我需要确保没有NULL值,因此表格应该如下所示

Opp_ID     Lead        Developer     Owner
--------------------------------------------------
1          Person_one  Person_two    Person_four
1          Person_one  Person_three  Person_four
1          Person_one  Person_five   Person_four

我的代码目前是:

SELECT
    ID,
    CASE WHEN Role_Name = 'Lead' THEN Role_User_Name ELSE NULL END AS Lead,
    CASE WHEN Role_Name = 'Developer' THEN Role_User_Name ELSE NULL END AS Developer,
    CASE WHEN Role_Name = 'Owner' THEN Role_User_Name ELSE NULL END AS Owner
FROM 
    [table1]
WHERE 
    Role_Name IN ('Lead','Developer','Owner')

不幸的是,这会返回以下结果:

Opp_ID     Lead        Developer     Owner
-------------------------------------------
1          Person_one  NULL          NULL
1          NULL        Person_two    NULL
1          NULL        Person_three  NULL
1          NULL        NULL          Person_four
1          NULL        Person_five   NULL

我认为要实现这一点,你需要重新加入代码,但我似乎无法让它发挥作用。

3 个答案:

答案 0 :(得分:1)

您可以切换到聚合:

SELECT ID,
       MAX(CASE WHEN Role_Name = 'Lead' THEN Role_User_Name END) AS Lead,
       MAX(CASE WHEN Role_Name = 'Developer' THEN Role_User_Name END) AS Developer,
       MAX(CASE WHEN Role_Name = 'Owner' THEN Role_User_Name END) AS Owner
FROM [table1]
WHERE  Role_Name IN ('Lead', 'Developer', 'Owner')
GROUP BY ID;

如果您可以有多个人,则可能需要使用STRING_AGG()

请注意,我删除了ELSE NULL。这是多余的。如果没有ELSE子句,则CASE表达式会在没有匹配项时返回NULL

答案 1 :(得分:0)

您还可以在 first_value 结果中使用 Pivot 功能,如下所示

See working demo

select 
    opp_id,
    lead=COALESCE([lead],FIRST_VALUE([Lead]) over( order by opp_id )),
    Developer=COALESCE([Developer],FIRST_VALUE([Developer]) over( order by opp_id )),
    Owner=COALESCE([Owner],FIRST_VALUE([Owner]) over( order by opp_id ))
from 
(select opp_id,Role_Name,
 Role_User_Name,
 rn=row_number() over( partition by Role_Name order by (select 1))
 from
 table1)
 src
pivot
(max(Role_user_name) for role_name in ([Lead],[Developer],[Owner]))p

答案 2 :(得分:0)

要应用每个开发人员并引导您的所有者Opp_ID,您需要以下内容:

SELECT o.opp_id
    , o.Role_User_Name AS Owner
    , l.Role_User_Name AS Lead
    , d.Role_User_Name AS Developer
FROM t1 AS o
LEFT OUTER JOIN t1 l ON o.opp_id = l.opp_id AND l.Role_Name = 'Lead'
LEFT OUTER JOIN t1 d ON o.opp_id = d.opp_id AND d.Role_Name = 'Developer'
WHERE o.Role_Name = 'Owner'

https://dbfiddle.uk/?rdbms=sqlserver_2017&fiddle=da4daea062534245bed474f93ffafbb7