【问题标题】:Get rows from comma separated list从逗号分隔列表中获取行
【发布时间】:2020-04-30 09:52:17
【问题描述】:

我想将逗号分隔的列表转换回表格。

例如。

我有一张像这样的桌子

Sid  roleid
  500    1,5,
  501    1,5,6,

我想要这样的输出

Sid roleid
500   1
500   5
501   1
501   5
501   6

请帮忙。

Create table #temp(Sid int,roleid varchar(100))
Insert into #temp values(500,'1,5,'),(501,'1,5,6,')

【问题讨论】:

标签: sql sql-server csv tsql


【解决方案1】:

使用 STRING_SPLIT() 表示您正在使用 SQL Server 2016(或更高版本)。

但是,STRING_SPLIT() 有一个很大的缺点:不能保证按预期顺序退回商品(请参阅docs, section "Remarks")。在我看来,这是一个绝对的表演终结者......

但是 - 幸运的是 - 在 v2016+ 中有一个快速且易于使用的解决方法:

Create table #temp(Sid int,roleid varchar(100))
Insert into #temp values(500,'1,5,'),(501,'1,5,6,');

SELECT t.[Sid]
      ,A.[key] AS position
      ,A.[value] AS roleid
FROM #temp t
CROSS APPLY OPENJSON(CONCAT('["',REPLACE(t.roleid,',','","'),'"]')) A
WHERE A.[value]<>'';

一个简单的数字数组 1,3,5 只需要括号就可以成为 JSON 数组 ([1,3,5])。在您的情况下,由于尾随逗号,我将其作为字符串处理。 1,3,5, 将被视为字符串数组:["1","3","5",""]。最后的空字符串被 WHERE 子句带走。剩下的就简单了……

除了STRING_SPLIT() docs 证明之外,OPENJSON 将反映项目在[key] 列中的位置:

当 OPENJSON 解析 JSON 数组时,该函数返回 JSON 文本中元素的索引作为键。

一般提示:避免将 STRING_SPLIT() 当作 lons,因为它的结果集中没有添加额外的键/位置列。

【讨论】:

  • 感谢您的解释!
【解决方案2】:

使用string_split()

select t.sid, spt.value
from table t cross apply
     string_split(t.roleid, ',') as spt
order by t.sid, spt.value;

【讨论】:

  • 我尽量避免STRING_SPLIT(),只要它不能保证排序顺序...(见我的回答)
【解决方案3】:

使用sring_split():

select t.sid, value rid
from t
cross apply string_split(t.roleid, ',') rid
order by t.sid, rid

【讨论】:

  • 我尽量避免STRING_SPLIT(),只要它不能保证排序顺序...(见我的回答)
  • @Shnugo:在这个用例中,排序并不重要,所以string_split() 就足够了。但总的来说,我同意你的看法。 OPENJSON 是一个不错的选择,赞成您的回答。
猜你喜欢
  • 2023-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-05-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多