2017-09-04 76 views
1

許多設備返回一個值。只有在變化,這個值被存儲在一個表:從排序不完整的數據集中提取最大值

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 

值可以在任何時間進入表(即日期不continiously增量)。多個設備可以在同一天存儲它們的值。

請注意,儘管表格中每個日期通常只有少數設備,但所有設備在該日期實際上都有一個值:這是迄今爲止存儲的最新設備。例如,在2017-07-02上只有設備A存儲了一個值。當日的BC的值是存儲在2017-07-01上的值;這些在-02上仍然有效,它們只是沒有改變。

要檢索給定日期的所有設備的值,例如,我使用這個:

select device,value from data inner join(select device,max(date)as date from data where date <= "2017-07-04" group by device)latestdate on data.device = latestdate.device and data .date = latestdate.date

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的MariaDB的

額外獎金:包括缺失日期-03,確切地說:返回給定日期的值,不一定是出現在表中的值。

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

提示:使用日曆表進行外連接以包含缺失的日期。 – jarlh

回答

1

我認爲最通用的方法是對每個日期使用單獨的查詢。取決於數據庫,確實有更簡單的方法。但是,讓一個SQLite的,MariaDB的工作,和Postgres是不會使用任何複雜的功能:

select '2017-07-01' as date, max(data.value) 
from data inner join 
    (select device, max(date) as date 
     from data 
     where date <= '2017-07-01' group by device 
    ) latestdate 
    on data.device = latestdate.device and data.date = latestdate.date 
union all 
select '2017-07-02' as date, max(data.value) 
from data inner join 
    (select device, max(date) as date 
     from data 
     where date <= '2017-07-02' group by device 
    ) latestdate 
    on data.device = latestdate.device and data.date = latestdate.date 
select '2017-07-03' as date, max(data.value) 
from data inner join 
    (select device, max(date) as date 
     from data 
     where date <= '2017-07-03' group by device 
    ) latestdate 
    on data.device = latestdate.device and data.date = latestdate.date 
select '2017-07-04' as date, max(data.value) 
from data inner join 
    (select device, max(date) as date 
     from data 
     where date <= '2017-07-04' group by device 
    ) latestdate 
    on data.device = latestdate.device and data.date = latestdate.date; 
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;