将逗号分隔的字符串转换为单独的行
我有一个像这样的 SQL 表:
SomeID | OtherID | Data |
---|---|---|
abcdef-..... | cdef123-... | 18,20,22 |
abcdef-..... | 4554a24-... | 17,19 |
987654-..... | 12324a2-... | 13,19,20 |
是否有一个查询可以执行像 SELECT OtherID, SplitData WHERE SomeID = 'abcdef-.......' 这样的查询,返回单独的行,像这样:
OtherID | SplitData |
---|---|
cdef123-... | 18 |
cdef123-... | 20 |
cdef123-... | 22 |
4554a24-... | 17 |
4554a24-... | 19 |
基本上将逗号处的数据拆分为单独的行?
我知道将逗号分隔的字符串存储到关系数据库中听起来很愚蠢,但消费者应用程序中的正常用例使其非常有用。
我不想在应用程序中进行拆分,因为我需要分页,因此我想在重构整个应用程序之前探索选项。
它是 SQL Server 2008
(非 R2)。
I have a SQL Table like this:
SomeID | OtherID | Data |
---|---|---|
abcdef-..... | cdef123-... | 18,20,22 |
abcdef-..... | 4554a24-... | 17,19 |
987654-..... | 12324a2-... | 13,19,20 |
Is there a query where I can perform a query like SELECT OtherID, SplitData WHERE SomeID = 'abcdef-.......'
that returns individual rows, like this:
OtherID | SplitData |
---|---|
cdef123-... | 18 |
cdef123-... | 20 |
cdef123-... | 22 |
4554a24-... | 17 |
4554a24-... | 19 |
Basically split my data at the comma into individual rows?
I am aware that storing a comma-separated
string into a relational database sounds dumb, but the normal use case in the consumer application makes that really helpful.
I don't want to do the split in the application as I need paging, so I wanted to explore options before refactoring the whole app.
It's SQL Server 2008
(non-R2).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(18)
函数
用例
或者只是一个具有多个结果集的选择
Function
Use case
Or just a select with multiple result set
我总是使用 XML 方法。确保使用有效的 XML。我有两个函数可以在有效的 XML 和文本之间进行转换。 (我倾向于去掉回车符,因为我通常不需要它们。
I always use the XML method. Make sure you use VALID XML. I have two functions to convert between valid XML and Text. (I tend to strip out the carriage returns as I don't usually need them.
从 SQL Server 2016 (13.x) 开始,工作选项可以使用
OPENJSON
此任务如下:输出:
检查演示此处。
From SQL Server 2016 (13.x) onwards, a working option can be using
OPENJSON
for this task as follows:Output:
Check the demo here.
下面适用于 sql server 2008
将获得所有笛卡尔积与原始表列加上拆分表的“项目”。
Below works on sql server 2008
Will get all Cartesian product with the origin table columns plus "items" of split table.
您可以使用以下函数来提取数据
You can use the following function to extract data
您可以使用 SQL Server 中精彩的递归函数:
示例表:
查询
输出
You can use the wonderful recursive functions from SQL Server:
Sample table:
The query
Output
最后,SQL Server 2016 结束了等待。他们引入了分割字符串函数,
STRING_SPLIT
:所有其他分割字符串的方法,如 XML、Tally 表、while 循环等,都被这个
STRING_SPLIT
函数所震撼。这是一篇关于性能比较的优秀文章:性能惊喜和假设: STRING_SPLIT。
对于旧版本,使用计数表这里是一个分割字符串函数(最佳可能的方法)
引用自Tally 哦!改进的SQL 8K“CSV Splitter”功能
Finally, the wait is over with SQL Server 2016. They have introduced the Split string function,
STRING_SPLIT
:All the other methods to split string like XML, Tally table, while loop, etc.. have been blown away by this
STRING_SPLIT
function.Here is an excellent article with performance comparison: Performance Surprises and Assumptions: STRING_SPLIT.
For older versions, using tally table here is one split string function(best possible approach)
Referred from Tally OH! An Improved SQL 8K “CSV Splitter” Function
检查这个
Check this
很晚了,但试试这个:
所以我们有这个:
tbl_Sample :
运行此查询后:
谢谢!
Very late but try this out:
So we were having this:
tbl_Sample :
After running this query:
Thanks!
截至 2016 年 2 月 - 请参阅 TALLY 表示例 - 从 2014 年 2 月开始,很可能会优于下面我的 TVF。为后人保留下面的原始帖子:
在上述示例中,我喜欢的重复代码太多。我不喜欢 CTE 和 XML 的性能。此外,还需要显式的
Id
,以便特定于订单的消费者可以指定ORDER BY
子句。As of Feb 2016 - see the TALLY Table Example - very likely to outperform my TVF below, from Feb 2014. Keeping original post below for posterity:
Too much repeated code for my liking in the above examples. And I dislike the performance of CTEs and XML. Also, an explicit
Id
so that consumers that are order specific can specify anORDER BY
clause.很高兴看到这个问题在 2016 版本中得到了解决,但对于所有未解决的问题,这里有上述方法的两个通用和简化版本。
XML 方法更短,但当然需要字符串来允许 xml 技巧(没有“坏”字符)。
XML 方法:
递归方法:
< strong>实际操作
XML-METHOD 2:Unicode 友好
Nice to see that it have been solved in the 2016 version, but for all of those that is not on that, here are two generalized and simplified versions of the methods above.
The XML-method is shorter, but of course requires the string to allow for the xml-trick (no 'bad' chars.)
XML-Method:
Recursive method:
Function in action
XML-METHOD 2: Unicode Friendly ???? (Addition courtesy of Max Hodges)
create function dbo.splitString(@input nVarchar(max), @Splitter nVarchar(99)) returns table as
Return
SELECT Split.a.value('.', 'NVARCHAR(max)') AS Data FROM
( SELECT CAST ('<M>' + REPLACE(@input, @Splitter, '</M><M>') + '</M>' AS XML) AS Data
) AS A CROSS APPLY Data.nodes ('/M') AS Split(a);
请参考下面的TSQL。 STRING_SPLIT 功能仅在兼容级别 130 及以上可用。
TSQL:
结果:
颜色
红色
蓝色的
绿色的
黄色的
黑色的
Please refer below TSQL. STRING_SPLIT function is available only under compatibility level 130 and above.
TSQL:
RESULT:
Colour
red
blue
green
yellow
black
我知道它有很多答案,但我想像其他人一样编写我的 split 函数版本,就像 string_split SQL Server 2016 本机函数一样。
这是问题的答案。
将拆分与其他拆分连接
拆分两次
拆分为
列 按范围生成行
I know it has a lot of answers, but I want to write my version of split function like others and like string_split SQL Server 2016 native function.
Here's a answer to question.
Joining Split with other split
Split two times
Split to columns
Generate rows by range
对上面的查询只做了很小的修改...
with only tiny little modification to above query...
通过创建这个分割字符串的函数 ([DelimitedSplit]),您可以对 SELECT 执行 OUTER APPLY。
测试
结果
By creating this function ([DelimitedSplit]) which splits a string, you could do an OUTER APPLY to your SELECT.
TEST
RESULT
以下是如何使用 STRING_SPLIT
结果的示例:
Here is an Example of How to use STRING_SPLIT
Result :