我有一个 SQL Server 表“水”,用于存储各个水表每小时使用的水量。我试图对所有使用情况进行求和,以确定每天的最大使用时间及其发生时间。我遇到的问题是弄清楚如何为每个 MAX 记录返回“time_local”。
我的初始查询 SUM 是每天每小时的所有使用情况。
SELECT SUM(consumption) AS Gallons,
time_local,
date_local
FROM water
WHERE consumption_period = 'HOUR' AND date_local > DATEADD(day,-2, GETDATE())
GROUP BY
time_local,
date_local
这将返回一天中每个小时的 SUM 消耗量。
加仑 | 本地时间 | 本地日期 |
---|---|---|
275,009 | 2023-12-19T15:00:00 | 2023-12-19 |
184,074 | 2023-12-19T06:00:00 | 2023-12-19 |
392,489 | 2023-12-18T12:00:00 | 2023-12-18 |
然后我使用初始语句作为子查询来获取每天的最大值
SELECT *
FROM
(SELECT
MAX(gallons) AS MaxHour,
date_local
FROM
(SELECT SUM(consumption) AS Gallons,
time_local,
date_local
FROM water
WHERE consumption_period = 'HOUR' AND date_local > DATEADD(day,-2, GETDATE())
GROUP BY
time_local,
date_local) AS t1
GROUP BY date_local) AS t2
这为我提供了每天的最大加仑数。
加仑 | 本地日期 |
---|---|
392,489 | 2023-12-18 |
315,744 | 2023-12-19 |
我遇到的问题是将这些整合在一起,这样我就可以报告每个最大值出现的“time_local”以获得这样的结果。
加仑 | 本地时间 | 本地日期 |
---|---|---|
392,489 | 2023-12-18T12:00:00 | 2023-12-18 |
315,744 | 2023-12-19T18:00:00 | 2023-12-19 |
我尝试加入 t1.gallons = t2.maxhour,但我做错了什么,因为系统告诉我“t1 不存在”。
有很多方法可以解决这个问题。这与您原来的布局非常接近。基本上,按小时计算的加仑使用量就可以了,然后 NOT EXISTS 会删除任何不是给定日期最大的记录 (t2.gallons > guah.gallons)。这可以避免额外的聚合,因此您可以保持列列表相同。
请注意,这将包括最大值相同的记录。对于像加仑这样的连续字段,这可能不太可能,但如果您缺少 0 或默认值等数据,则可能会发生这种情况。在这种情况下,您需要指定某种决胜规则。
with gallon_usage_by_hour as (
select time_local,
date_local,
sum(consumption) as gallons,
from water
where consumption_period = 'HOUR' and date_local > dateadd(day,-2, getdate())
group
by time_local,
date_local
)
select *
from gallon_usage_by_hour guah
where not exists
(
select 1
from gallon_usage_by_hour t2
where guah.date_local = t2.date_local
and t2.gallons > guah.gallons
)
您可以使用窗口函数
WITH CTE AS (
SELECT SUM(consumption) AS Gallons,
time_local,
date_local
, ROW_NUMBER() OVER (PARTITION BY date_local ORDER BY SUM(consumption) DESC) rn
FROM water
WHERE consumption_period = 'HOUR' AND date_local > DATEADD(day,-2, GETDATE())
GROUP BY
time_local,
date_local)
SELECT
Gallons
,time_local
,date_local
FROM CTE
WHERE rn = 1