【问题标题】:Aggregate over the column that is not in group by list聚合不在按列表分组的列
【发布时间】:2018-03-20 09:52:56
【问题描述】:

例如我有下表:

declare @table table(val int, dt datetime)
insert into @table values
(10, '2018-3-20 16:00'),
(12, '2018-3-20 14:00'),
(14, '2018-3-20 12:00'),
(16, '2018-3-20 10:00'),
(10, '2018-3-19 14:00'),
(12, '2018-3-19 12:00'),
(14, '2018-3-19 10:00'),
(10, '2018-3-18 12:00'),
(12, '2018-3-18 10:00')

我尝试使用 group by 中的列进行聚合,没关系:

select day, MAX(val) as max_by_value from
(
select DATEPART(DAY, dt) as day, val from @table
) q
group by day

返回:

day max_by_value
18  12
19  14
20  16

现在我需要按一天中的时间计算最大值,所以我需要 10 作为每天的结果。 我尝试使用over,但它说Column '@table.dt' is invalid in the select list because it is not contained in either an aggregate function or the GROUP BY clause.

select DATEPART(DAY, dt), MAX(val) as max_by_value
,ROW_NUMBER() over (partition by DATEPART(DAY, dt) order by dt desc) as max_by_date
from @table
group by DATEPART(DAY, dt)

我了解为什么会收到此错误,但不知道如何解决我的问题。能否请您帮忙找到填充[max_by_date] 列的方法?

结果我希望得到以下输出:

day max_by_value max_by_time
18  12           10
19  14           10
20  16           10

【问题讨论】:

  • “现在我需要一天中的时间最大值”。除非我遗漏了什么,否则只需按dt分组...
  • 我同时需要 3 列 - [day], [max_by_value], [max_by_time]
  • 我不确定我是否在关注。请编辑您的问题以包含所需的结果。
  • 完成,文本中描述了“所以我每天需要 10 个结果”

标签: sql-server tsql


【解决方案1】:

从2012版本开始,可以使用First_value窗口功能:

SELECT  DISTINCT DATEPART(DAY, dt), 
        MAX(val) OVER (partition by DATEPART(DAY, dt)) as max_by_value,
        FIRST_VALUE(val) OVER (partition by DATEPART(DAY, dt) order by dt desc) as max_by_date
FROM @table

注意:我在 MAX 函数中使用了 OVER 子句,而不是使用 group by

在 2008 版本中,您可以改用子查询:

SELECT  DISTINCT DATEPART(DAY, dt), 
        MAX(val) OVER (partition by DATEPART(DAY, dt)) as max_by_value,
        (
            SELECT TOP 1 val
            FROM @table as t1
            WHERE DATEPART(DAY, t1.dt) = DATEPART(DAY, t0.dt)
            ORDER BY dt DESC
        ) as max_by_date
FROM @table as t0

【讨论】:

  • 非常感谢。我只是担心性能。由于distinct 将删除大量计算记录,因此这一事实似乎会影响性能。你怎么看?
  • Distinct 肯定会减慢查询速度。您需要测试具有相关量的实际数据,看看这是否太慢。如果是,请检查执行计划。
  • 是的,我会检查的。无论如何,您知道如何更改查询以提高性能吗?我的桌子太大了,如果可能的话,我相信我需要更有效的方法。
猜你喜欢
  • 2014-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多