【问题标题】:Find Peaks Of Data By Values And Sum Over Time Period In SQL在 SQL 中按值查找数据峰值并在一段时间内求和
【发布时间】:2021-09-21 05:29:27
【问题描述】:

对于 SQL 查询/存储过程,我希望在一段时间内按类型查找给定值的峰值总和。此外,如果峰值在给定时间段内没有下降趋势,则不应计算在内。

数据,例如:

Type Amount Date
AAA 10 2021-07-11
AAA 15 2021-07-11
AAA 20 2021-07-11
AAA 25 2021-07-11 *Need this peak
AAA 20 2021-07-11
AAA 15 2021-07-11
AAA 10 2021-07-11
AAA 15 2021-07-11
AAA 20 2021-07-11
AAA 25 2021-07-11
AAA 30 2021-07-11 *Need this peak added to previous peak
AAA 20 2021-07-11
AAA 15 2021-07-11
AAA 10 2021-07-11
BBB 10 2021-07-11
BBB 20 2021-07-11
BBB 30 2021-07-11 *Need this peak
BBB 20 2021-07-11
BBB 10 2021-07-11
CCC 10 2021-07-11
CCC 20 2021-07-11
CCC 30 2021-07-11
CCC 20 2021-07-11
CCC 10 2021-07-11
CCC 20 2021-07-11
CCC 30 2021-07-11
CCC 40 2021-07-11 *This peak won't count because the downtrend happens the next day
CCC 30 2021-07-12
CCC 20 2021-07-12
CCC 10 2021-07-12

给定日期 2021-07-11 的结果应该是:

Type Total
AAA 55
BBB 30

(不包括CCC,因为在给定日期没有下降趋势)

我什至不确定从哪里开始,除了可能会获取每行的值,而每行的后续行较少(开始下降趋势)。

【问题讨论】:

  • 。 . SQL 表代表 无序 集。如果没有对行进行排序(可能使用date 上的时间组件),则无法回答问题。

标签: sql sql-server azure-data-factory


【解决方案1】:

鉴于当前的表结构,这是不可能的。您至少需要另一列来指示每条记录的顺序。否则查询将无法保证

AAA 10  2021-07-11

总会来之前

AAA 15  2021-07-11

没有迹象表明为什么第二个比第一个晚。

【讨论】:

  • 关系数据库中没有内置排序 - 您必须以某种方式自己添加。
  • 是的,这完全有道理。它实际上是一个时间戳,而不仅仅是一个日期。我试图简化示例,但您是绝对正确的。
【解决方案2】:

让我假设您的date 列有一个时间组件。您实际上需要对行进行显式排序,而日期还不够。

如果是这样,您可以使用lead()lag()

select t.*
from (select t.*,
             lag(amount) over (partition by type, convert(date, date) order by date) as prev_amount,
             lead(amount) over (partition by type, convert(date, date) order by date) as next_amount
      from t
     ) t
where prev_amount < amount and amount > next_amount;

编辑:

对于最终的聚合:

select type, sum(amount)
from (select t.*,
             lag(amount) over (partition by type, convert(date, date) order by date) as prev_amount,
             lead(amount) over (partition by type, convert(date, date) order by date) as next_amount
      from t
     ) t
where prev_amount < amount and amount > next_amount;
group by type;

【讨论】:

  • 它实际上是一个时间戳,而不仅仅是一个日期。抱歉,我试图简化示例。我想知道使用滞后和领先的方法,但不确定。我怎样才能确保我得到每组(或每个示例的每个“类型”)并将这些合格的峰值相加?
  • 如果我们正在寻找局部最大值,第二个比较不应该是amount &gt; next_amount吗?
  • @GordonLinoff,这非常有用。非常感谢。
猜你喜欢
  • 2014-11-28
  • 1970-01-01
  • 2015-02-24
  • 2021-08-29
  • 2014-05-15
  • 1970-01-01
  • 1970-01-01
  • 2023-02-17
  • 1970-01-01
相关资源
最近更新 更多