【问题标题】:SQL create distinct comma separated listsSQL 创建不同的逗号分隔列表
【发布时间】:2015-01-22 21:33:53
【问题描述】:

我有一个接受逗号分隔列表的存储过程,然后使用带引号的字符串和括号制作该列表的副本,然后在动态 sql 语句中使用它们来构建具有灵活列数的数据透视表。

我的问题是,有时我的用户会提交包含重复项的列表,这会导致数据透视查询失败。所以我想以某种方式选择与我的逗号分隔的字符串不同的选项。

我是这样操作初始字符串的:

Declare @data varchar(max) = '150593, 150593, 150603, 150578, 150604'

Declare @bracketed varchar(max) = ''
Declare @quoted varchar(max) = ''

select @bracketed = @bracketed + quotename(rtrim(ltrim(Value))) + ', ',  
      @quoted = @quoted + quotename(rtrim(ltrim(Value)), '''') + ', '
from [dbo].[fnSplitStringAsTable](@data, ',')

Select @bracketed = LEFT(@bracketed, len(@bracketed) - 1), 
       @quoted = LEFT(@quoted, len(@quoted) - 1)

我想我应该能够在此查询中的某处添加 DISTINCT,
但我不能让它工作。如何从逗号分隔的列表中选择不同的列表?

【问题讨论】:

  • @AaronBertrand - 你怎么记得 3 年前的答案...我不记得我上周说了什么。
  • @AaronBertrand - 虽然我同意你的记忆力令人印象深刻,但你能告诉我那篇文章的哪一部分是相关的吗?我没看到...
  • 抱歉,我以为您正在尝试创建分组连接列表。有关删除重复项的功能,请参阅this。我怀疑它比您当前的功能更有效。

标签: sql sql-server csv pivot


【解决方案1】:

作为替代解决方案,您可以在 xml 中进行重复数据删除并转换回 varchar

Declare @data varchar(max) = '150593, 150593, 150603, 150578, 150604'
set @data= (select '''' + cast(cast('<d>'+replace(@data, ', ',',</d><d>')+'</d>'  as xml).query('distinct-values(/d)') as varchar) +'''')
select @data

【讨论】:

  • 这很漂亮@Jayvee!
【解决方案2】:

我想我们可以在你制作表格后添加 distinct,如下所示:

select @bracketed = @bracketed + quotename(rtrim(ltrim(Value))) + ', ',  
      @quoted = @quoted + quotename(rtrim(ltrim(Value)), '''') + ', '
from (
  SELECT DISTINCT Value FROM [dbo].[fnSplitStringAsTable](@data, ',')
) T

如果失败,试试这个:

select @bracketed = @bracketed + quotename(Value) + ', ',  
      @quoted = @quoted + quotename(Value), '''') + ', '
from (
  SELECT DISTINCT RTRIM(LTRIM(Value)) AS Value FROM [dbo].[fnSplitStringAsTable](@data, ',')
) T

【讨论】:

  • - 因其简单而诱人,但不会消除重复。此外,需要子查询的别名。
  • @MAW74656 - 为什么不消除重复项?它在你的测试中失败了吗?
  • 没有线索....但它没有这样做。我的测试仍然抛出错误The column '150593' was specified multiple times for 'p'
  • @MAW74656 见编辑。如果这也失败了,您必须向我们展示您正在使用的实际代码。
  • @MAW74656 - 是的 LTRIM+RTRIM,您现在可以将它们从选择部分中取出并获得一些价值(双关语)。它之所以有效,是因为您的 split 函数在某处留下了额外的空白并且 DISTINCT 有效。
【解决方案3】:

使用一点动态 sql,您可以从字符串变量中选择不同的值到表变量中,然后将这些值放回原始变量中:

declare @data varchar(max) = '150593, 150593, 150603, 150578, 150604'
declare @table table(data varchar(10))

set @data = 'select distinct value from (values (''' +
        replace(@data,', ','''),(''') + ''')) as v(value)'

insert into @table
    exec(@data)

set @data = ''
select @data = @data + data +
    case row_number() over(order by data desc)
        when 1 then ''
        else ','
    end
from @table
order by data asc

select @data

【讨论】:

  • 他已经在使用一个函数将值放入一个表中——为什么不直接操纵它而不是疯狂地使用字符串技巧?
  • @RonSmith - Hogan 是对的,尽管我喜欢你的 row_number 技巧来判断你是否需要逗号。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 1970-01-01
  • 2013-02-26
  • 2021-09-12
相关资源
最近更新 更多