【问题标题】:SQL averaging multiple time periods of the same datasetSQL平均同一数据集的多个时间段
【发布时间】:2010-09-14 02:52:42
【问题描述】:

我有以下疑问:

SELECT AVG(val) from floatTable
WHERE tagindex IN(1,2,3,4)
AND DateAndTime > '$first_of_year'

它返回今年迄今为止为这四个标签测量的所有值的平均值。由于我已经在检索此数据,我如何获取自月初、第一周和午夜以来的数据?我已经将这些日期计算为 $first_of_month、$first_of_week 和 $midnight。我正在尝试最小化查询,并希望有人可以帮助我创造一些 SQL 魔法,以便在单个查询或一组优化的查询中返回这些数据。这个查询平均需要 300 秒,所以我想尽量少做。

提前谢谢你。

【问题讨论】:

  • 如果您不想对数据库进行太多往返,您可以简单地将这些平均值放在一个庞大的查询中的子查询中。据我的数学专业告诉我,平均值无法拆分或组合,因此您确实需要在不同的时间段内重新计算它们。
  • @Denis,请参阅 RedFilter 的回答。子查询不需要额外访问数据库,但需要在查询中进行额外的逻辑读取 - 因此查询的总时间可能长达四倍。至于平均值,大多数版本的 SQL 在聚合计算中完全省略了 NULL 值 - 因此 RedFilter 查询中的四个不同表达式将被正确计算(因为不满足条件的值将被评估为 NULL)。
  • @Mark Ba​​nnister,在 RedFilter 发布他的答案的那一刻,我默默地承认了我的失礼,并立即从中吸取了教训,我想留下我的评论以供后人学习我的快速假设。

标签: sql optimization query-optimization average


【解决方案1】:
SELECT AVG(case when DateAndTime > '$first_of_year' then val end) as FirstOfYear,
       AVG(case when DateAndTime > '$first_of_month' then val end) as FirstOfMonth,
       AVG(case when DateAndTime > '$first_of_week' then val end) as FirstOfWeek,
       AVG(case when DateAndTime > '$midnight' then val end) as Midnight
from floatTable 
WHERE tagindex IN(1,2,3,4) 
    and DateAndTime > '$first_of_year' 

为了提高性能,请确保您在列 DateAndTimetagIndex 上有索引。

【讨论】:

  • 效果很好...为什么它的运行速度比我原来的查询快很多?
  • 它不应该比您问题中的查询快,但它可能也不会(很多)慢,尽管添加了您需要的额外列。当您提到“原始查询”时,您是指问题中的那个,还是您有一个来获得您想要的所有其他平均值?这可能是缓存问题 - 您已经运行了一个查询,因此 SQL Server 将这些数据保存在内存中。
  • @user438199 请确认您的意思 > 我想您的意思可能是 >= '$first_of_year'
  • 请注意,$first_of_week 可能在 1 月的 $first_of_year 之前,但本周将被视为 12 月的最后一周,因为您只考虑 $first_of_yeear 之后的几天,实际上可能是 1 月 1 日。不过,这取决于您的文化要求。
  • 谢谢大家。 @Nathan Koop >= 在技术上是正确的,但由于返回的数据量很大,因此影响可以忽略不计。
猜你喜欢
  • 1970-01-01
  • 2014-09-07
  • 1970-01-01
  • 1970-01-01
  • 2016-09-13
  • 1970-01-01
  • 1970-01-01
  • 2021-11-22
  • 1970-01-01
相关资源
最近更新 更多