【问题标题】:Select distinct list of words if there are multiple words per record如果每条记录有多个单词,则选择不同的单词列表
【发布时间】:2018-10-09 14:32:04
【问题描述】:

请考虑下表:

words
-------------
foo
bar
bar, baz
foobar, foo, bar, dolor
lorem, ipsum
ipsum

我需要一个查询来编译words 的不同列表,如下所示:

foo
bar
baz
foobar
dolor
lorem
ipsum

如果我还需要用逗号分隔words,我该怎么做?

【问题讨论】:

  • 有 100 个(可能是 1,000 个)问题询问如何在 Stack Overflow 上的 SQL Server 中拆分字符串,其中大部分标记为重复项。这些答案有什么问题?到目前为止,您做了哪些尝试(发布您的代码)以及遇到了什么问题?
  • 我想问你为什么有这样一张桌子。您的设计通过将一堆值填充到单个元组中来违反 1NF。如果你有一个正确规范化的模式,你甚至不会有问题,因为查询会很简单。修复设计,您的痛苦就会消失。
  • 你做过研究吗???你用谷歌搜索过你的问题吗???网络上有大量示例。
  • 您的问题是如何获取distinct 值列表按第一次出现排序

标签: sql-server tsql sql-server-2012


【解决方案1】:

在 Sql Server 2012 中,您可以使用 Web 上可用的拆分函数(例如 DelimitedSplit8K 可用 here)来隔离单个单词。使用cross apply,您可以将函数应用于源表中的所有行:

declare @words table (list_of_words varchar(8000))
insert into @words values
('foo')
,('bar')
,('bar, baz')
,('foobar, foo, bar, dolor')
,('lorem, ipsum')
,('ipsum')

select distinct(ltrim((rtrim(Item)))) as single_words 
from @words
cross apply [dbo].[DelimitedSplit8K](list_of_words,',')

结果:

从 SQL Server 2016 开始,您可以使用 string_split 来隔离单个单词:

declare @words table (list_of_words varchar(max))
insert into @words values
('foo')
,('bar')
,('bar, baz')
,('foobar, foo, bar, dolor')
,('lorem, ipsum')
,('ipsum')

select distinct(trim(value)) as single_words 
from @words
cross apply string_split(list_of_words,',')

【讨论】:

  • DelimitedSplit8K 是 Jeff Moden 的一个函数。您没有提供链接,但更令人不安的是它无法接收 varchar(max)。如果您修改他的代码以接受性能将是可怕的。他在文章中明确指出了这一点。你可以找到Jeff的文章here
  • @SeanLange 你是绝对正确的:我的错。我编辑了答案,还添加了文章的链接。感谢您的提示!
【解决方案2】:
DECLARE @words TABLE (
    Info    VARCHAR(100)
)

INSERT @words
VALUES
('foo'),
('bar'),
('bar, baz'),
('foobar, foo, bar, dolor'),
('lorem, ipsum'),
('ipsum')


SELECT DISTINCT word
FROM (
    SELECT CAST('<X>'+replace(w.Info,', ','</X><X>')+'</X>' as XML) as x 
    FROM @words w
) T1
    CROSS APPLY ( 
        SELECT n.D.value('.','varchar(100)') as word
        FROM T1.x.nodes('X') as n(D)
    ) T2

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-07-23
    • 1970-01-01
    • 2017-09-15
    • 2023-03-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多