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

无聚合函数实现日期与小时的Pivot转换

嘿,我完全懂你这个困扰——用MAX/MIN这类聚合函数做Pivot时,硬生生把同一日期下的多个小时捏成了单个值,根本不是你想要的按小时逐条展示的效果。别慌,咱们调整一下思路和查询结构就能搞定!

问题根源:分组维度搞反了

你之前的查询大概率是按日期分组来做Pivot,导致每个日期列只能返回该日期的最大/最小小时,而不是所有关联的小时。要实现「小时为行、日期为列」的Pivot效果,核心是把分组维度换成hour,让每个小时单独占一行,再对每个日期判断该小时是否存在。

解决方案1:静态Pivot(已知所有日期)

如果你的日期范围是固定的,直接用CASE WHEN结合GROUP BY hour就能实现,这里用MAX/MIN其实完全没问题(因为每个小时+日期组合最多一个值,聚合函数只是满足语法要求):

SELECT 
  hour,
  MAX(CASE WHEN date = '2024-05-01' THEN hour END) AS '2024-05-01',
  MAX(CASE WHEN date = '2024-05-02' THEN hour END) AS '2024-05-02',
  MAX(CASE WHEN date = '2024-05-03' THEN hour END) AS '2024-05-03'
FROM your_table
GROUP BY hour
ORDER BY hour ASC;

执行后你会得到:每一行对应一个小时,各日期列显示该日期是否包含这个小时(有就显示小时值,没有则为NULL),而且小时会严格按顺序排列。

解决方案2:动态Pivot(日期不固定)

如果你的日期是动态变化的,没法提前写死列名,就用动态SQL自动生成日期列:

DECLARE @cols AS NVARCHAR(MAX),
        @query AS NVARCHAR(MAX);

-- 自动提取所有不重复的日期,转成列名格式
SELECT @cols = STRING_AGG(QUOTENAME(date), ', ')
FROM (SELECT DISTINCT date FROM your_table) AS dates;

-- 构建动态Pivot查询
SET @query = '
SELECT hour, ' + @cols + '
FROM (
  SELECT date, hour FROM your_table
) AS src
PIVOT (
  MAX(hour) FOR date IN (' + @cols + ')
) AS pvt
ORDER BY hour ASC;';

-- 执行动态SQL
EXEC sp_executesql @query;

这个方案会自动适配所有存在的日期,结果同样是按小时排序的「小时行+日期列」结构。

额外需求:同一日期显示多个小时(逗号分隔)

如果你的需求是每个日期列显示该日期下的所有小时(用逗号拼接),可以把聚合函数换成STRING_AGG,比如静态写法:

SELECT 
  hour,
  STRING_AGG(CASE WHEN date = '2024-05-01' THEN CAST(hour AS VARCHAR) END, ', ') 
    WITHIN GROUP (ORDER BY hour) AS '2024-05-01',
  STRING_AGG(CASE WHEN date = '2024-05-02' THEN CAST(hour AS VARCHAR) END, ', ') 
    WITHIN GROUP (ORDER BY hour) AS '2024-05-02'
FROM your_table
GROUP BY hour
ORDER BY hour ASC;

这样同一日期同一小时的记录会被拼接成逗号分隔的字符串(如果有重复的话可以加DISTINCT去重)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:54:38