【问题标题】:How to select peak amount dates from table with date and amount columns如何从具有日期和金额列的表中选择峰值金额日期
【发布时间】:2012-11-20 21:20:00
【问题描述】:

我有一个包含 2 列的表格,日期和金额。我希望能够找到 x 天的数量峰值。因此,如果我有下表并且正在寻找 3 天的峰值,这意味着该日期的金额高于之前或之后 3 天的任何一天,那么将选择该日期。

date         amount
2012-09-04 | 53137.47
2012-09-05 | 53137.2
2012-09-06 | 53137.54
2012-09-07 | 53138.58
2012-09-10 | 53138.73
2012-09-11 | 53138.28
2012-09-12 | 53138.22
2012-09-13 | 53138.48
2012-09-14 | 53140.14
2012-09-17 | 53139.82
2012-09-18 | 53139.86
2012-09-19 | 53140.01
2012-09-20 | 53139.75
2012-09-21 | 53139.82
2012-09-24 | 53139.01
2012-09-25 | 53138.93
2012-09-26 | 53138.48
2012-09-27 | 53138.83
2012-09-28 | 53138.62

应该选择 2012-09-10, 2012-09-14

我尝试过使用联接和派生表,但似乎无法正常工作。

尝试了以下方法:

    select * from a WHERE  
amount=(select MAX(amount) from a where 
date<date_add(date,interval 3 day) and 
date>date_sub(date,interval 3 day));

    SELECT a1.*
    FROM a AS a1
    JOIN a AS a2 ON 
(select * from a1 where 
a2.DATE < a1.DATE + 3 and 
a2.DATE > a1.DATE - 3) myalias
    WHERE a1.amount > a2.amount;

【问题讨论】:

  • 是以 +/- 3 个日历日的间隔(如您的查询尝试所示)或表格中连续 +/- 3 个日期的间隔(如所示)计算的最大值通过从您想要的结果中排除 2012-09-19)?
  • 我的意思是根据表格中的连续日期进行计算,现在我发现我没有这样做。

标签: mysql sql date-range


【解决方案1】:

为了找到一个日期区间的最大值,你必须将中心日期的记录加入到区间内其他日期的记录中,然后按中心日期分组。

试试这个查询:

SELECT a1.date, a1.amount, max(a2.amount) AS highest
FROM tbl a1 LEFT JOIN tbl a2
ON a2.date BETWEEN date_sub(a1.date, interval 3 DAY)
           AND date_add(a1.date, interval 3 DAY)
GROUP BY a1.date, a1.amount
HAVING a1.amount = highest
ORDER BY a1.date;

要根据连续记录而不是日历日获得答案,您必须使用行号来增加表(通过将表与自身进行自联接),然后将此扩展表自联接以在比较金额时,它自己会选择每个日期 +/- 3 行内的行:

SELECT t3.date FROM
  (SELECT t1.date AS date, t1.amount AS amount, count(t2.date) AS rownum
   FROM tbl t1
   INNER JOIN tbl t2
   ON t2.date <= t1.date
   GROUP BY t1.date, t1.amount) AS t3
LEFT JOIN
  (SELECT t1.date AS date, t1.amount AS amount, count(t2.date) AS rownum
   FROM tbl t1
   INNER JOIN tbl t2
   ON t2.date <= t1.date
   GROUP BY t1.date, t1.amount) AS t4
ON t3.rownum <> t4.rownum
AND t3.rownum - t4.rownum  BETWEEN -3 AND 3
AND t4.amount >= t3.amount
WHERE t4.date IS NULL
ORDER BY t3.date

这适用于 MySQL 和 PostgreSQL,也应该适用于其他数据库引擎。 在 MySQL 以外的其他数据库中,可以通过对两个子查询使用 CTE 来简化它。

查看此SQLfiddle 进行测试。

【讨论】:

  • 太棒了!这非常适合日历日。如上所述,我需要尝试调整表格中的连续日期。谢谢!
  • 糟糕。我要求澄清,然后我误读了答案。
  • 再次感谢。我正在使用 MySQL,所以正如你所说,我需要找到一种不同的方法。当我尝试您的示例时,我在 MySQL 中收到以下错误:ERROR 1235 (42000): This version of MySQL doesn't yet support 'LIMIT & IN/ALL/ANY/SOME subquery'
  • 检查在 MySQL 中也可以使用的查询的更新答案。
  • 是的,更新后的答案在 MySQL 中效果很好。我永远不会想到这一点。这远远超出了我的新手技能。我向你卓越的智慧低头。谢谢!
猜你喜欢
  • 1970-01-01
  • 2016-03-27
  • 2020-11-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-16
  • 1970-01-01
相关资源
最近更新 更多