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

如何将SQL查询结果按活动分组到同一行?

解决方案:合并同一活动的每日工时到单行

看起来你想要把同一活动下的每日工时记录合并到同一行,而不是每个单独的时间条目都占一行。咱们可以通过字符串聚合函数和调整分组逻辑来实现这个需求,具体修改方案如下:

原查询的问题分析

你的原查询在GROUP BY里包含了WorkDate和[Time],这会导致每一条时间记录都被单独分组,从而生成多行结果。要实现按活动聚合,需要去掉这两个分组字段,同时用聚合函数把同一天的多个时间合并成一个字符串。

修改后的SQL查询(适用于SQL Server 2017+)

SELECT 
    Employee,
    Departmentname,
    [Week],
    Activity,
    -- 合并周一的所有时间,用逗号分隔并按时间排序
    STRING_AGG(CASE WHEN DATENAME(dw, WorkDate) = 'MONDAY' THEN CONVERT(VARCHAR(5), [Time], 108) END, ', ') 
        WITHIN GROUP (ORDER BY [Time]) AS Monday,
    -- 合并周二的所有时间
    STRING_AGG(CASE WHEN DATENAME(dw, WorkDate) = 'TUESDAY' THEN CONVERT(VARCHAR(5), [Time], 108) END, ', ') 
        WITHIN GROUP (ORDER BY [Time]) AS Tuesday,
    -- 合并周三的所有时间
    STRING_AGG(CASE WHEN DATENAME(dw, WorkDate) = 'WEDNESDAY' THEN CONVERT(VARCHAR(5), [Time], 108) END, ', ') 
        WITHIN GROUP (ORDER BY [Time]) AS Wednesday,
    -- 合并周四的所有时间
    STRING_AGG(CASE WHEN DATENAME(dw, WorkDate) = 'THURSDAY' THEN CONVERT(VARCHAR(5), [Time], 108) END, ', ') 
        WITHIN GROUP (ORDER BY [Time]) AS Thursday,
    -- 合并周五的所有时间
    STRING_AGG(CASE WHEN DATENAME(dw, WorkDate) = 'FRIDAY' THEN CONVERT(VARCHAR(5), [Time], 108) END, ', ') 
        WITHIN GROUP (ORDER BY [Time]) AS Friday,
    -- 合并周六的所有时间
    STRING_AGG(CASE WHEN DATENAME(dw, WorkDate) = 'SATURDAY' THEN CONVERT(VARCHAR(5), [Time], 108) END, ', ') 
        WITHIN GROUP (ORDER BY [Time]) AS Saturday,
    -- 计算该活动的总工时,格式化为HH:MM:SS
    CONVERT(VARCHAR(8), DATEADD(millisecond, SUM(DATEDIFF(millisecond, 0, CAST([Time] AS DATETIME))), 0), 108) AS TotalHRW
FROM TimeSheet
WHERE 
    [Week] = 18  -- 用=代替LIKE更合适,因为Week是数值类型的精确匹配
    AND Departmentname = 'Returns'
    AND Employee = 'Hand Batis'
GROUP BY 
    Employee, Departmentname, [Week], Activity  -- 仅按核心维度分组,确保同一活动聚合为一行
ORDER BY 
    [Week], Employee

关键修改点说明

  1. 字符串聚合:用STRING_AGG函数把同一活动、同一工作日的所有时间合并成逗号分隔的字符串,WITHIN GROUP (ORDER BY [Time])还能保证时间按先后顺序排列。
  2. 分组调整:GROUP BY只保留Employee, Departmentname, [Week], Activity,确保同一活动的所有记录被聚合到单行。
  3. 总工时计算:调整总工时逻辑,对该活动下所有时间的毫秒数求和后再转换为标准时间格式,结果更准确。
  4. 条件优化:把LIKE替换为=,因为你的筛选是精确匹配,LIKE在这里不仅没必要,还可能影响查询性能。

兼容旧版SQL Server(2016及更早)的写法

如果你的SQL Server版本不支持STRING_AGG,可以用STUFF+FOR XML PATH的方式实现字符串合并,以周一列为例:

STUFF((
    SELECT ', ' + CONVERT(VARCHAR(5), [Time], 108)
    FROM TimeSheet t2
    WHERE 
        t2.Employee = t1.Employee
        AND t2.Departmentname = t1.Departmentname
        AND t2.[Week] = t1.[Week]
        AND t2.Activity = t1.Activity
        AND DATENAME(dw, t2.WorkDate) = 'MONDAY'
    ORDER BY t2.[Time]
    FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 2, '') AS Monday

需要把每个工作日的列都替换成这种写法,GROUP BY和总工时计算逻辑保持不变。

内容的提问来源于stack exchange,提问作者Tony Batista

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 07:14:55