【问题标题】:SQL Server 2016: Use FOR XML and STUFF with Multiple Join QuerySQL Server 2016:将 FOR XML 和 STUFF 用于多连接查询
【发布时间】:2023-03-30 23:28:01
【问题描述】:

我有一个查询用于报告目的,列出未提交季度报告的雇主和未提交的季度。这是我的查询:

with employerIds as (select distinct Employerid
                from employerTransaction),
quarters as (select distinct QId
                    from employerTransaction)
select ei.EmployerId, e.EmployerName, q.QId
from employerIds as ei
cross join quarters as q
left join employerTransaction as et
        on et.EmployerId = ei.EmployerId
        and et.QId = q.QId
join employer as e
        on e.EmployerId = ei.EmployerId
where et.employerid is null
group by ei.employerid, q.QId
order by ei.EmployerId, q.QId

查询结果如下:

    EmployerId   EmployerName                 QId
    1            Potato Inc                   20193
    1            Potato Inc                   20202
    1            Potato Inc                   20203
    2            Donuts LLC                   20202
    2            Donuts LLC                   20203
    3            Pineapple Logistics          20191
    3            Pineapple Logistics          20192
    3            Pineapple Logistics          20193
    3            Pineapple Logistics          20194

我想要的是将 QId 列合并为每个 EmployerId 的一行,如下所示:

     EmployerId   EmployerName                 QId
     1            Potato Inc                   20193, 20202, 20203
     2            Donuts LLC                   20202, 20203
     3            Pineapple Logistics          20191, 20192, 20193, 20194

我正在使用 Sql Server 2016,所以很遗憾我无法利用 string_agg(),而必须使用 FOR XMLstuff()。我不确定如何在具有多个连接的查询上使用stuff()。感谢您提供任何帮助。

【问题讨论】:

  • 您不要为此使用 STUFF 函数。为此,您可以使用 FOR XML(子)查询。 STUFF 函数仅用于通过删除前导(或尾随)分隔符来美化最终结果。

标签: sql sql-server-2016 stuff


【解决方案1】:

试试这个解决方案

Select  ei.EmployerId, 
        e.EmployerName ,
        ISNULL(STUFF((Select Distinct ', ' + Cast(QId  As Varchar(500))
                        From employerTransaction As Q
                        Where  et.QId = q.QId
                        FOR XML PATH('')), 1, 1, ''),'-') As [NewQID]
From employerIds As ei
Left Join employerTransaction as et on et.EmployerId = ei.EmployerId and et.QId = q.QId
Join employer as e on e.EmployerId = ei.EmployerId
Where et.employerid is null
Group By ei.employerid, e.EmployerName

【讨论】:

  • 如果使用逗号和空格 (', ') 作为分隔符,则分隔符为 2 个字符长。您也应该在 STUFF 函数的第三个参数中反映这一点。那应该是 2 而不是 1。否则,[NewQID] 列中的结果值将以空格开头。
【解决方案2】:

这是for xml path 子句在起作用。 stuff 只是去掉前面的 ','

with sampledata as (
   -- your original query here
)
select EmployerId, EmployerName,
   stuff( (select ','+ cast(t2.Qid as varchar(5))
          from sampledata t2
          where t2.EmployerId = t1.EmployerId and t2.EmployerName = t1.EmployerName
          for xml path ('')), 1, 1,'') qids
from sampledata t1
group by EmployerId, EmployerName

db<>fiddle

返回

EmployerId  EmployerName    qids
1   Potato Inc  20193,20202,20203
2   Donuts LLC  20202,20203
3   Pineapple Logistics 20191,20192,20193,20194

【讨论】:

  • 感谢您的回复。 Qid 正在聚合,但我在运行查询时看到重复的 Employerid 返回。例如,在我在问题中提供的第二个示例输出中,Potato inc 退货 3 次,Donut LLC 退货两次,Pineapple Logistics 退货 4 次,等等。
  • ...for xml path ('')).value('text()', 'nvarchar(max)'), 1, 1....
  • @BGonzaga, .. my fiddle 完全使用您的样本数据。我没有看到重复。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
  • 2015-09-21
  • 1970-01-01
  • 1970-01-01
  • 2016-11-08
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多