以前有人问过Turning a Comma Separated string into individual rows。这适用于一列,但我有一个扩展问题。如果我想拆分两个(或更多)相关列,该怎么办?也就是说,如果我有这样的数据(使用前一篇文章中的数据作为基础):
| SomeID | OtherID | Data | RelatedData |
+----------------+-------------+-----------+-------------+
| abcdef-..... | cdef123-... | 18,20,22 | xxx,,yyy |
| abcdef-..... | 4554a24-... | 17,19 | a,bb |
| 987654-..... | 12324a2-... | 13,19,20 | r,s,t |
并希望返回如下行:
| SomeID | OtherID | Data | RelatedData |
+----------------+-------------+------+-------------+
| abcdef-..... | cdef123-... | 18 | xxx |
| abcdef-..... | cdef123-... | 20 | |
| abcdef-..... | cdef123-... | 22 | yyy |
| abcdef-..... | 4554a24-... | 17 | a |
| abcdef-..... | 4554a24-... | 19 | bb |
| ... | ... | ... | ... |
由于其简单性,我希望使用STRING_SPLIT,但我找不到让它工作的方法。这不起作用:
select OtherID, cs1.Value, cs2.Value
from yourtable
cross apply STRING_SPLIT (Data, ',') cs1
cross apply STRING_SPLIT (RelatedData, ',') cs2
有什么建议吗?
答案 0 :(得分:4)
我同意有关此设计的评论。最好将数据标准化。
要使用string_split()
执行此操作,您可以将row_number()
解决方法用于序数,如下所示:
;with cs1 as (
select SomeId, OtherId, x.Value
, ItemNumber = row_number() over (partition by t.SomeId, t.OtherId order by (Select Null))
from t
cross apply string_split(Data,',') x
)
, cs2 as (
select SomeId, OtherId, x.Value
, ItemNumber = row_number() over (partition by t.SomeId, t.OtherId order by (Select Null))
from t
cross apply string_split(RelatedData,',') x
)
select cs1.SomeId, cs1.OtherId, cs1.Value, cs2.Value
from cs1
inner join cs2
on cs1.SomeId = cs2.SomeId
and cs1.OtherId = cs2.OtherId
and cs1.ItemNumber = cs2.ItemNumber
返回:
+--------------+-------------+-------+-------+
| SomeId | OtherId | Value | Value |
+--------------+-------------+-------+-------+
| 987654-..... | 12324a2-... | 13 | r |
| 987654-..... | 12324a2-... | 19 | s |
| 987654-..... | 12324a2-... | 20 | t |
| abcdef-..... | 4554a24-... | 17 | a |
| abcdef-..... | 4554a24-... | 19 | bb |
| abcdef-..... | cdef123-... | 18 | xxx |
| abcdef-..... | cdef123-... | 20 | |
| abcdef-..... | cdef123-... | 22 | yyy |
+--------------+-------------+-------+-------+
我认为使用包含序数的自定义函数更简单。例如,Jeff Moden的分隔内联表值函数:
select SomeId, OtherId, cs1.Item, cs2.Item
from t
cross apply dbo.delimitedsplit8K(Data,',') cs1
cross apply dbo.delimitedsplit8K(RelatedData,',') cs2
where cs1.ItemNumber = cs2.ItemNumber
返回相同的结果。
拆分字符串参考:
string_split()
in SQL Server 2016 : Follow-Up #1 - Aaron Bertrand string_split()**
- Solomon Rutzky