从一系列不完整的数据集中获取最大值

时间:2017-09-04 09:23:42

标签: sql

许多设备返回一个值。只有在更改时,此值才会存储在表格中:

Device  Value  Date
B       5      2017-07-01
C       2      2017-07-01
A       3      2017-07-02
C       1      2017-07-04
A       6      2017-07-04

值可以在任何日期输入表格(即日期不会连续增加)。有些设备可能会在同一天存储它们的值。

请注意,即使表中的每个日期通常只有少数设备,但所有设备实际上都具有该日期的值:它是在此之前存储的最新设备。例如,在2017-07-02上,只有设备 A 存储了一个值。该日期的 B C 的值是2017-07-01上存储的值;这些在-02仍然有效,它们只是没有改变。

要检索给定日期的所有设备的值,例如2017-07-04,我正在使用它:

从data.device = latestdate.device和data.date = latestdate中选择设备,来自数据内部联接的值(选择设备,最大值(日期)作为日期<= "2017-07-04"逐个设备的数据的日期)。日期

Device  Value
A       6
B       5
C       1

问题:我想读取给定范围内所有日期的所有设备的最大值。结果集如下:

Date        max(value)
2017-07-01  5
2017-07-02  5
2017-07-04  6

..我不知道是否可以仅使用SQL。到目前为止,我所得到的一切都在一系列特殊的联合和分组中丢失了。

(数据库是 sqlite3 。通用 SQL 会很好,但我仍然很高兴听到特定于其他数据库的解决方案,尤其是 PostgreSQL < / strong>或 MariaDB 。)

额外奖励:准确地包括缺失日期-03:在给定日期返回值,不一定是表格中显示的值。

Date        max(value)
2017-07-01  5
2017-07-02  5
2017-07-03  5
2017-07-04  6

2 个答案:

答案 0 :(得分:1)

我认为最常用的方法是对每个日期使用单独的查询。根据数据库的不同,肯定有更简单的方法。但是,获得适用于SQLite,MariaDB和Postgres的一个不会使用任何复杂的功能:

Dumb Components

答案 1 :(得分:0)

这应该是您的问题的解决方案。 它应该是跨数据库的,因为大多数数据库都支持OVER子句。 您应该创建一个包含所有日期的表(查询中的“ALL_DATE”),否则每个数据库都有一个特定的方法来执行它而没有表。


WITH GROUPED_BY_DATE_DEVICE AS (
  SELECT DATE, DEVICE, SUM(VALUE) AS VALUE FROM DEVICE_INFO
  GROUP BY DATE, DEVICE
), GROUPED_BY_DATE AS (
  SELECT A.DATE, MAX(VALUE) AS VALUE
  FROM ALL_DATE A
  LEFT JOIN GROUPED_BY_DATE_DEVICE B
  ON A.DATE = B.DATE
  GROUP BY A.DATE
)
SELECT DATE, MAX(VALUE) OVER (ORDER BY DATE) AS MAX_VALUE 
FROM GROUPED_BY_DATE
ORDER BY DATE;