2013-02-21 66 views
3

我有兩個表(一個顯示發送給客戶的所有程序的記錄,另一個顯示用戶對所有程序執行操作的記錄)。我的最終目標是計算髮送給用戶的這些程序中有多少人受到了處理。我現在有辦法做到這一點,但有一個問題。程序可能會在一天內多次發送給用戶(我將以20爲例)。如果用戶在24小時內對該程序採取行動,我不希望它被計爲19個沒有采取行動的程序和1個被採取行動的程序。我希望它計數爲1作用於程序,0失敗。SQL根據其他行刪除重複行

包含發送給客戶的程序的表需要過濾掉,以便發送給客戶的每個程序僅在每24小時期間顯示一次。

我的解決方案是有一個「窗口」類型的東西,這樣一旦程序發送給客戶,它就被鎖定了24小時,因此它不會出現在我的'發送給客戶的程序中'多次查詢。

我有這樣的一個表:

Customer Time Program 
----------------------------------- 
1   8:05 a 
1   10:30 a 
1   11:30 a 
1   12:30 b 
1   1:25 a 
2   9:38 b 
2   10:38 c 
2   1:36 c 
2   2:40 c 
2   3:41 b 
. 
. 
. 

我希望得到一個表(查詢,而不是刪除)在一定時間框架內消除每個客戶重複的程序(迷惑我知道!)

這裏是我想要的(用例如3小時的時間框架):

Customer Time Program 
----------------------------------- 
1   8:05 a 
1   11:30 a 
1   12:30 b 
2   9:38 b 
2   10:38 c 
2   2:40 c 
2   3:41 b 
. 
. 
. 
+1

您使用的是什麼RDBMS? – Taryn 2013-02-21 15:31:25

+0

什麼樣的列是「時間」日期時間,時間戳等?你還使用什麼rdbms和版本? – 2013-02-21 15:33:58

+0

「時間」的數據類型是什麼?對於任何代碼來說,確定'1:36'在*'10:38'之後是非常困難的。甲骨文, – 2013-02-21 15:34:02

回答

2

試試這個:

select * 
from t 
where not exists (select 1 from t t2 
        where t2.customer = t.customer and 
         t2.program = t.program and 
         t2.time - t.time < 3.0/24 and 
         t2.time > t.time 
       ) 

日期時間算術取決於數據庫,但這對於其中的很多算法都有效。

+0

這是在正確的方向,但它不會顯示想要的結果。 – 2013-02-21 15:36:56

+0

@ypercube。 。 。我假設你指的是問題的「相同程序」部分。我只是在 – 2013-02-21 15:48:25

+0

中加上了這個號碼。除此之外,這不是OP想要的。我認爲,「滾動窗口」的要求只能通過遞歸查詢來解決。 – 2013-02-21 15:49:37

1

我認爲你的意思可以通過遞歸查詢來解決(僅)。這裏是一個解決方案:

WITH cte AS 
    (SELECT 
     customer, program, time, 
     ROW_NUMBER() 
      OVER (PARTITION BY customer, program 
        ORDER BY time) 
      AS rn, 
     MIN(time) 
      OVER (PARTITION BY customer, program 
        ORDER BY time 
        RANGE BETWEEN 3.0/24 FOLLOWING 
          AND UNBOUNDED FOLLOWING) 
      AS next_time 
    FROM a 
) 

SELECT 
    customer, time, program 
FROM 
    cte 
START WITH rn = 1 
CONNECT BY PRIOR customer = customer 
     AND PRIOR program = program 
     AND PRIOR next_time = time 
ORDER BY 
    customer, time, program ; 

您也可以替換MIN(time)以上FIRST_VALUE(time)並得到相同的結果。這可能更有效率。

測試在SQL-Fiddle

效率上了一個大表可能不會很好。您可以嘗試使用較小的一組數據運行查詢。

你至少應該添加這個指標,所以它的索引掃描:

CREATE INDEX ix    -- choose a name for the index 
    ON tableX     -- the table name 
    (customer, program, time) ; 

你也可以跳過最終排序或改變它,所以它更類似於使用的索引:

ORDER BY 
    customer, program, time ;