使用distinct with stuff/for xml path('')

Use*_*716 4 sql sql-server-2008

基于这里问题中概述的方法:

将许多行连接成单个文本字符串?

我想在串联字符串中只放置唯一值.我的代码目前是:

select rc.Routage
    , COUNT(distinct rc.Event)
    , STUFF((select ', ' + cast(rcA.Event as varchar)
            from Receiving rcA
            where rcA.supplier = 'user'
                and rcA.DATETIME > '20170322'
                and rc.Routage=rcA.Routage
            for xml path(''))
        , 1, 1, '')
from Receiving rc
where rc.supplier = 'user'
    and rc.DATETIME > '20170322'
group by rc.Routage
order by COUNT(distinct rc.Event)desc
Run Code Online (Sandbox Code Playgroud)

这给了我期望的输出,但我想消除stuff/for xml path字段中的重复值.

我已经尝试了各种组合distinctgroup by在stuff/xml部分,但不能正确拼凑它们.

为了澄清,对于COUNT(distinct rc.Event)= 2,我希望看到来自stuff子句的2个不同的事件.我怎样才能做到这一点?

Gor*_*off 8

select distinct在子查询中使用:

select rc.Routage,
       count(distinct rc.Event),
       stuff((select distinct ', ' + cast(rcA.Event as varchar(max))
              from Receiving rcA
              where rcA.supplier = 'user' and
                    rcA.DATETIME > '20170322' and
                    rc.Routage = rcA.Routage
              for xml path('')
             ), 1, 2, '')
from Receiving rc
where rc.supplier = 'user' and rc.DATETIME > '20170322'
group by rc.Routage;
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 在SQL Server中,永远不要使用varchar()(或相关类型)没有长度.默认值因上下文而异,您(可能)引入了一个很难找到的错误.
  • 您希望stuff()删除两个字符,而不是1,因为您有一个逗号后跟一个空格.
  • 此公式假定Event没有XML特殊字符.如果这是一个问题,很容易调整.

此外,如果消除子查询中的重复项,则此类查询通常会更快:

select rc.Routage, rc.numEvents,
       stuff((select distinct ', ' + cast(rcA.Event as varchar(max))
              from Receiving rcA
              where rcA.supplier = 'user' and
                    rcA.DATETIME > '20170322' and
                    rc.Routage = rcA.Routage
              for xml path(''), type
             ).value('.', 'varchar(max)'
                    ), 1, 2, ''
            )
from (select rc.Routage, count(distinct rc.Event) as numEvents
      from Receiving rc
      where rc.supplier = 'user' and rc.DATETIME > '20170322'
      group by rc.Routage
     ) rc;
Run Code Online (Sandbox Code Playgroud)