You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在PARTITION BY查询中聚合OS.Id生成IdAggregate列?

实现SQL分区内ID的逗号分隔聚合列

你的现有查询已经按OS.returnmessageid、OS.unitnumber、OD.messageutc、OP.messagetype做了分区,要新增IdAggregate列存储同一分区下所有OS.Id的逗号分隔列表,可按以下方式实现:

情况1:SQL Server 2017及以上版本(推荐)

直接使用官方提供的STRING_AGG字符串聚合函数,语法简洁高效:

SELECT OS.returnmessageid,
       OS.tagconfig,
       CASE
         WHEN OP.messagetype = 202
              AND OS.datapointid IN ( 1, 3 ) THEN
         CONVERT(NVARCHAR(max), OS.lookupvalue)
         ELSE Try_convert(Nvarchar(max), OS.value)
       END AS Value,
       OS.unitnumber,
       OD.messageutc,
       OP.messagetype,
       OS.isproccessed,
       OS.id,
       -- 新增的IdAggregate列,聚合同一分区下的所有OS.Id
       STRING_AGG(OS.id, ',') WITHIN GROUP (ORDER BY OS.id) 
         OVER (PARTITION BY OS.returnmessageid, OS.unitnumber, OD.messageutc, OP.messagetype) AS IdAggregate,
       Row_number()
         OVER (
           partition BY OS.returnmessageid, OS.unitnumber, OD.messageutc,
         OP.messagetype
           ORDER BY OS.returnmessageid, OS.unitnumber, OD.messageutc,
         OP.messagetype )
           AS RowNum
FROM   ooocommreturnmessagesscaling OS
       LEFT JOIN ooocommreturnmessagesparsing OP
              ON OP.id = OS.returnmessageid
       LEFT JOIN ooocommreturnmessagedetails OD
              ON OP.returnmessageid = OD.id

说明

  • STRING_AGG(OS.id, ',') 指定要聚合的字段为OS.id,分隔符用逗号
  • WITHIN GROUP (ORDER BY OS.id) 可选,用来定义聚合后ID的排序顺序
  • OVER (PARTITION BY ...) 沿用你现有查询的分区字段,确保只聚合同一分区内的ID

情况2:SQL Server 2016及更早版本

如果你的版本不支持STRING_AGG,可以用STUFF结合FOR XML PATH的经典方法实现:

SELECT OS.returnmessageid,
       OS.tagconfig,
       CASE
         WHEN OP.messagetype = 202
              AND OS.datapointid IN ( 1, 3 ) THEN
         CONVERT(NVARCHAR(max), OS.lookupvalue)
         ELSE Try_convert(Nvarchar(max), OS.value)
       END AS Value,
       OS.unitnumber,
       OD.messageutc,
       OP.messagetype,
       OS.isproccessed,
       OS.id,
       -- 新增的IdAggregate列
       STUFF((
           SELECT ',' + CAST(OS2.id AS VARCHAR(max))
           FROM ooocommreturnmessagesscaling OS2
           LEFT JOIN ooocommreturnmessagesparsing OP2 ON OP2.id = OS2.returnmessageid
           LEFT JOIN ooocommreturnmessagedetails OD2 ON OP2.returnmessageid = OD2.id
           -- 匹配同一分区的条件
           WHERE OS2.returnmessageid = OS.returnmessageid
             AND OS2.unitnumber = OS.unitnumber
             AND OD2.messageutc = OD.messageutc
             AND OP2.messagetype = OP.messagetype
           ORDER BY OS2.id
           FOR XML PATH(''), TYPE
       ).value('.', 'VARCHAR(max)'), 1, 1, '') AS IdAggregate,
       Row_number()
         OVER (
           partition BY OS.returnmessageid, OS.unitnumber, OD.messageutc,
         OP.messagetype
           ORDER BY OS.returnmessageid, OS.unitnumber, OD.messageutc,
         OP.messagetype )
           AS RowNum
FROM   ooocommreturnmessagesscaling OS
       LEFT JOIN ooocommreturnmessagesparsing OP
              ON OP.id = OS.returnmessageid
       LEFT JOIN ooocommreturnmessagedetails OD
              ON OP.returnmessageid = OD.id

说明

  • 子查询通过FOR XML PATH('')将同一分区的ID拼接成带前置逗号的字符串(比如,1,2,3)
  • STUFF(..., 1, 1, '') 去掉字符串开头的第一个逗号,最终得到1,2,3的格式
  • 子查询的连接条件与主查询完全一致,确保只匹配同一分区的数据

内容的提问来源于stack exchange,提问作者Alex Gordon

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 20:26:09