2015-02-24 67 views
1

請假設我有一個名爲MYDATA Oracle表,有如下內容:Oracle查詢窗口功能

NAME, D1,   D2 
A,  01/01/2010, 02/03/2010 
B,  03/03/2010, 20/03/2010 
C,  10/03/2010, 20/09/2010 
D,  10/12/2010, 31/12/2010 


Insert into MYDATA 
    (NAME, D1, D2) 
Values 
    ('A', TO_DATE('01/01/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('03/02/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS')); 
Insert into MYDATA 
    (NAME, D1, D2) 
Values 
    ('B', TO_DATE('03/03/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('03/20/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS')); 
Insert into MYDATA 
    (NAME, D1, D2) 
Values 
    ('C', TO_DATE('03/10/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('09/20/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS')); 
Insert into MYDATA 
    (NAME, D1, D2) 
Values 
    ('D', TO_DATE('12/10/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS'), TO_DATE('12/31/2010 00:00:00', 'MM/DD/YYYY HH24:MI:SS')); 
COMMIT; 

我想與標記「S」具有重疊的時間間隔記錄:在這種情況下,記錄B和記錄C重疊。

我寫了下面的Oracle查詢:

SELECT name, D1, D2, WMSYS.WM_CONCAT (OVERLAPPING) 
    FROM (SELECT T1.name, T1.D1, T1.D2, NULL OVERLAPPING 
       FROM MYDATA T1, MYDATA T2 
      WHERE NOT ((T1.D1, T1.D2) OVERLAPS (T2.D1, T2.D2)) 
        AND T1.NAME <> T2.NAME 
      UNION 
      SELECT T1.name, T1.D1, T1.D2, 'S' 
       FROM MYDATA T1, MYDATA T2 
      WHERE ((T1.D1, T1.D2) OVERLAPS (T2.D1, T2.D2)) 
        AND T1.NAME <> T2.NAME) 
GROUP BY NAME, D1, D2; 

結果是:

NAME, D1,   D2,   WMSYS.WM_CONCAT(OVERLAPPING) 
A, 01/01/2010, 02/03/2010, NULL 
B, 03/03/2010, 20/03/2010, S 
C, 10/03/2010, 20/09/2010, S 
D, 10/12/2010, 31/12/2010, NULL 

正如你所看到的,MYDATA加入本身的表 'S' 重疊的記錄標記。 我知道,當一個表連接時,相應的查詢可以使用Oracle窗口函數重寫。

最後,使用Oracle窗口函數重寫查詢如下:

SELECT NAME, 
      D1, 
      D2 
    FROM (SELECT T1.NAME, 
        T1.D1, 
        T1.D2 
       FROM MYDATA T1, MYDATA T2 
      WHERE ((T1.D1, T1.D2) OVERLAPS (T2.D1, T2.D2)) 
        AND T1.NAME <> T2.NAME) 
GROUP BY NAME, D1, D2; 

你能我請幫忙重寫查詢,避免了自加入?

非常感謝您考慮我的要求。

回答

2

您可以使用caseleadlag

SELECT D.*, 
     CASE 
      WHEN LAG (D1) OVER (ORDER BY D1) IS NOT NULL 
       AND (LAG (D1) OVER (ORDER BY D1), LAG (D2) OVER (ORDER BY D1)) 
         OVERLAPS (D1, D2) 
       OR LEAD (D1) OVER (ORDER BY D1) IS NOT NULL 
        AND (LEAD (D1) OVER (ORDER BY D1), 
         LEAD (D2) OVER (ORDER BY D1)) 
         OVERLAPS (D1, D2) 
      THEN 
       'S' 
      ELSE 
       'N' 
     END 
      OVERLAP 
    FROM MYDATA D; 

結果:

NAME            D1  D2  OVERLAP 
-------------------------------------------------- --------- --------- ------- 
A             01-JAN-10 02-MAR-10 N  
B             03-MAR-10 20-MAR-10 S  
C             10-MAR-10 20-SEP-10 S  
D             10-DEC-10 31-DEC-10 N 
+0

非常感謝你對你的幫助!接受答案! – UltraCommit 2015-02-24 16:13:10

+1

不客氣的人。這是一個很好的做法,總是尋找分析解決方案,所以,很高興幫助:) – Aramillo 2015-02-24 16:17:49