簡體   English   中英

是否有更有效的方法來編寫 SQL 以按日期和列值對計數進行分組

[英]Is there a more efficient way to write SQL to group counts by date and column value

我有一個 -1 或 1 的狀態值定期存儲在H2數據庫中,我需要計算過去 12 個月內按月存儲的 -1 和 1 的數量。 以下代碼有效,但我將在多個地方將其用作派生表,並想知道是否有更有效的方法。

SELECT  STATUS_CODE AS STATUS,
    COUNT(*) AS STATUS_COUNT,
    CASE    
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-1,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 1'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-2,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 2'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-3,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 3'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-4,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 4'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-5,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 5'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-6,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 6'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-7,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 7'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-8,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 8'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-9,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 9'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-10,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 10'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-11,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 11'
        WHEN EXTRACT(EPOCH FROM DATEADD(MONTH,-12,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME)   THEN 'MONTH 12'
        ELSE 'DONE' 
    END AS WEEK_RANGE
FROM    MY_TABLE 
WHERE   EXTRACT(EPOCH FROM DATEADD(MONTH,-12,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME) 
GROUP BY STATUS_CODE,  WEEK_RANGE
order by week_range

運行之前的代碼的結果。

在此處輸入圖片說明

您可以使用DATEDIFF()動態計算log_entry_time和當前日期之間的差異,以月為單位:

SELECT  
    status_code AS status,
    COUNT(*) AS status_count,
    DATEDIFF(MONTH, log_entry_time, CURRENT_DATE) month_range
FROM MY_TABLE 
WHERE log_entry_time  >= DATEADD(MONTH, -12, CURRENT_DATE)
GROUP BY status_code, month_range
ORDER BY month_range

如果LOG_ENTRY_TIME是類似date的數據類型,請不要將其轉換為紀元進行比較,因為這樣做會阻止在該列上使用索引。 您可以改為進行日期比較,如上述查詢的WHERE子句所示。

這樣的東西會更有用嗎?

SELECT  STATUS_CODE AS STATUS,
        COUNT(*) AS STATUS_COUNT,
        EXTRACT(YEAR FROM LOG_ENTRY_TIME) || '-' || EXTRACT(MONTH FROM LOG_ENTRY_TIME)
FROM    MY_TABLE 
WHERE   EXTRACT(EPOCH FROM DATEADD(MONTH,-12,CURRENT_DATE)) < EXTRACT(EPOCH FROM LOG_ENTRY_TIME) 
GROUP BY STATUS_CODE,  WEEK_RANGE
order by week_range;

這與您的查詢所做的有點不同,但該查詢提供實際月份值(例如,“2019-12”)用於可追溯性,而不是通用的“Month N”標簽。 即使不完全是你想要達到的目標,也許這會給出一個想法。

(我不確定 Oracle 的TRUNC()的 H2 等價物是什么,但這將有助於收集整月的數據,而不是前一個月的當天;這就是我想要實現的目標。)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM