簡體   English   中英

(SQL)如何根據使用OVER計算的值進行條件過濾

[英](SQL) How to conditionally filter based on a value calculated using OVER

我有通過工作流程的客戶日志。 我想做兩件事,而我都在努力。

首先是:我希望通過在工作流開始時輸入第一個狀態(輸入狀態0)來篩選出沒有開始的客戶。

其次是:對於剩余的客戶,我想知道他們在工作流程的每個步驟中花費了多少時間。

每條記錄都有:

  • CUSTOMER_ID(整數)
  • STATE(整數)
  • ACTION(輸入或退出此狀態,即varchar)
  • UPDATE_DT(輸入時間戳)

我嘗試執行一個查詢,該查詢將允許我獲取按客戶和狀態分組的進入和退出的時間戳,如下所示:

SELECT
    CUSTOMER_ID,
    STATE,
    MIN(UPDATE_DT) AS ENTRY_DATE,
    MAX(UPDATE_DT) AS EXIT_DATE
FROM LOG_DATA
GROUP BY CUSTOMER_ID, STATE
ORDER BY CUSTOMER_ID, STATE;

但是我立即遇到了一些問題。 該查詢將正常運行,但:

  • 我還沒有刪除沒有從狀態0進入的客戶
  • 並非所有客戶都能保證每個州都有出入境日期,所以有時我的MIN / MAX無效

我試圖通過在選擇中引入一個附加屬性來關注第一個問題:

MIN(STATE) OVER(PARTITION BY CUSTOMER_ID) AS EARLIEST_STATE

但是隨后遇到了一些問題。 我無法將EARLIEST_STATE包含為WHERE或GROUP BY HAVING的條件,因為對於WHERE而言,它不存在,並且GROUP BY不允許我包含EARLIEST_STATE。

正如我所認為的那樣,這種情況變得越來越糟-MIN(STATE)最多只能證明客戶的STATE = 0,但不能證明他們有一條記錄說ACTION =“ enter”和STATE =0。所以這種方法不僅失敗因為我無法讓它運行,但因為從邏輯上講也是不正確的。

我知道我可以對SELECT進行多個SELECT,但這感覺很笨拙,我想學習正確的方法。 處理1000萬行數據也無濟於事,因此效率很重要。

我使用的是Postgres 9.5,在這種情況下我無法控制數據庫技術或數據模式。

這會很慢,但是我可以使用我的Python來執行此操作,但是我真的很想知道使用數據庫執行此操作的正確方法。

如果我理解正確,那么對於結果集中的任何客戶,您都希望至少有一行行,其中Action = 'Enter'並且state = 0 這暗示了一個窗口函數:

SELECT CUSTOMER_ID, STATE,
       MIN(UPDATE_DT) AS ENTRY_DATE,
       MAX(UPDATE_DT) AS EXIT_DATE,
FROM (SELECT l.*,
             SUM(CASE WHEN ACTION = 'Enter' AND state = 0 THEN 1 ELSE 0 END) OVER (PARTITION BY CUSTOMER_ID) as num_validenter
      FROM LOG_DATA l
     ) l
WHERE num_validenter > 0
GROUP BY CUSTOMER_ID, STATE
ORDER BY CUSTOMER_ID, STATE

暫無
暫無

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

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