根据值将 SQL 列拆分为多列
Splitting SQL column into multiple columns based on value
我有一个 table 如下所示
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
值,所以 table 应该像下面的
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')
不幸的是 returns 这些结果:
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
我假设要使它正常工作,您需要重新加入代码本身,但我似乎无法让它正常工作。
您可以切换到聚合:
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
表达式 returns NULL
当没有匹配时。
您还可以使用 first_value function on Pivot 结果如下
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
要应用每个开发人员并带领您的所有者进行 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
我更喜欢使用交叉连接
select o.opp_id,
o.role_user_name o,
l.role_user_name l,
d.role_user_name d
from t1 o cross join t1 l cross join t1 d
where o.role_name = 'Owner'
and l.role_name = 'Lead'
and d.role_name = 'Developer'
enter image description here
我有一个 table 如下所示
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
值,所以 table 应该像下面的
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')
不幸的是 returns 这些结果:
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
我假设要使它正常工作,您需要重新加入代码本身,但我似乎无法让它正常工作。
您可以切换到聚合:
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
表达式 returns NULL
当没有匹配时。
您还可以使用 first_value function on Pivot 结果如下
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
要应用每个开发人员并带领您的所有者进行 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
我更喜欢使用交叉连接
select o.opp_id,
o.role_user_name o,
l.role_user_name l,
d.role_user_name d
from t1 o cross join t1 l cross join t1 d
where o.role_name = 'Owner'
and l.role_name = 'Lead'
and d.role_name = 'Developer'
enter image description here