【问题标题】:Using distinct with stuff/for xml path('')使用 distinct with stuff/for xml path('')
【发布时间】:2017-03-23 11:44:44
【问题描述】:

我只想将连接字符串中的唯一值放在一起。我的代码目前是:

select rc.Routage
    , COUNT(distinct rc.Event)
    , STUFF((select ', ' + cast(rcA.Event as varchar)
            from Receiving rcA
            where rcA.supplier = 'user'
            for xml path(''))
        , 1, 1, '')
from Receiving rc
where rc.supplier = 'user'
group by rc.Routage
order by COUNT(distinct rc.Event)desc

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

我在 stuff/xml 部分尝试了 distinct 和 group by 的各种组合,但无法正确组合。

为了澄清,对于COUNT(distinct rc.Event) = 2,我想从 stuff 子句中看到 2 个不同的事件。我该怎么做?

【问题讨论】:

    标签: sql sql-server-2008


    【解决方案1】:

    在子查询中使用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;
    

    注意事项:

    • 在 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;
    

    【讨论】:

      【解决方案2】:

      在 XML 处理接近它之前,在子查询中执行 distinct:

      select rc.Routage
          , COUNT(distinct rc.Event)
          , STUFF((select ', ' + cast(rcA.Event as varchar)
      
                  from (select distinct Event from Receiving a
                        where supplier = 'user'
                         and DATETIME > '20170322'
                         and rc.Routage=a.Routage
                  ) rcA
      
                  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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-12-16
        • 2015-09-21
        • 1970-01-01
        • 2021-02-10
        • 2021-05-19
        • 1970-01-01
        • 2020-12-02
        相关资源
        最近更新 更多