SQL创建不同的逗号分隔列表

SQL创建不同的逗号分隔列表,sql,sql-server,csv,pivot,Sql,Sql Server,Csv,Pivot,我有一个存储过程,它接受逗号分隔的列表,然后用带引号的字符串和括号复制该列表,然后在动态sql语句中使用这些字符串和括号来构建具有灵活列数的透视表 我的问题是,有时我的用户提交一个包含重复项的列表,这会导致pivot查询失败。所以我想以某种方式选择与逗号分隔字符串不同的字符串 下面是我如何操作初始字符串: Declare @data varchar(max) = '150593, 150593, 150603, 150578, 150604' Declare @bracketed varcha

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

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

下面是我如何操作初始字符串:

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,
但我不能让它工作。如何从逗号分隔的列表中选择distinct?

我想我们可以在创建表格后添加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

我想我们可以在制作表格后添加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

使用一点动态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

使用一点动态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

作为替代解决方案,您可以在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

作为替代解决方案,您可以在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


@你怎么记得三年前的答案。。。我不记得上周我说了什么。@AaronBertrand-虽然我同意你的记忆力很好,但你能告诉我那篇文章的哪一部分是相关的吗?我看不到…对不起,我以为你是想列一个列表。有关删除重复项的函数,请参见。我怀疑它比你现在的功能更有效。@AaronBertrand-你怎么记得3年前的答案。。。我不记得上周我说了什么。@AaronBertrand-虽然我同意你的记忆力很好,但你能告诉我那篇文章的哪一部分是相关的吗?我看不到…对不起,我以为你是想列一个列表。有关删除重复项的函数,请参见。我怀疑它比您当前的函数更有效。-它的简单性很吸引人,但并不能消除重复项。此外,子查询还需要别名。@MAW74656-为什么不消除重复项?你考试不及格吗?没有线索。。。。但事实并非如此。我的测试仍然会抛出错误,因为为'p'@MAW74656多次指定了列'150593'。请参见编辑。如果这也失败了,那么您必须向我们展示您正在使用的实际代码。@MAW74656-是的LTRIM+RTRIM,您现在可以从选择的部分中取出这些代码,并获得一些预期的双关语。它之所以能工作,是因为你的分割函数在某个地方留下了额外的空白,而且效果不同。-它的简单性很吸引人,但不能消除重复项。此外,子查询还需要别名。@MAW74656-为什么不消除重复项?你考试不及格吗?没有线索。。。。但事实并非如此。我的测试仍然会抛出错误,因为为'p'@MAW74656多次指定了列'150593'。请参见编辑。如果这也失败了,那么您必须向我们展示您正在使用的实际代码。@MAW74656-是的LTRIM+RTRIM,您现在可以从选择的部分中取出这些代码,并获得一些预期的双关语。它之所以有效,是因为你的拆分函数在某个地方留下了额外的空格,并且可以独立工作。他已经在使用一个函数将值放入表中-为什么不只是操纵它,而不是疯狂地使用字符串技巧呢?@RonSmith-Hogan是对的,尽管我喜欢你的行号诀窍来判断你是否需要逗号。他已经在使用一个函数将值放入一个表中了——为什么不直接操纵它,而不要疯狂地使用字符串诀窍呢?@Ronmith-Hogan是对的,尽管我喜欢你的行号诀窍来判断你是否需要逗号。这太巧妙了@Jayvee!这太狡猾了@Jayvee!