2014-09-30 123 views
0

我只發現了一些稍微不同的例子,由於我的sql技能非常有限,我無法適應我的需求。查詢SQL查詢有n次連續失敗嘗試

我有3個revelant列的表:

ItemID Date  Result 
1  1.2.2014 A 
5  6.4.2014 B 
9  7.4.2014 A 
1  8.4.2014 A 
1  9.4.2014 A 
1  10.4.2014 A 

我想找到有特定結果的項目(假設A)連續3次。在上面的示例中,它將是第1項。日期通常不是連續的。

它應該在Oracle SQL中工作。

非常感謝您的幫助!

+2

連續3次基於什麼?日期和結果組合?有沒有關鍵的專欄? – NMK 2014-09-30 09:02:09

+0

感謝您的幫助。 我想過濾具有特定結果的項目,讓我們連續說'A'。因此,如果項目1有結果A,那麼B然後是A,然後是A,它不會被包括在內。只有它有A,然後A又一次A.日期可以是任何時間,它們不是每天或每週或每月。只有序列是重要的。 我希望我現在解釋得夠好。沒有關鍵列。 – 2014-09-30 12:03:32

回答

0

不知道這是否是最佳實現它的方式,但它的工作原理。我創建了下面的表格把你的示例數據爲:

CREATE TABLE DATE_RESULT(
    ITEM_ID INT, 
    DATE_COL DATE, 
    RESULT_COL VARCHAR2(255 CHAR) 
); 

然後運行這個查詢:

SELECT ITEM_ID FROM(
    SELECT 
    ITEM_ID, 
    TO_CHAR(DATE_COL,'DD-MON-YYYY') AS DATE_COL, 
    RESULT_COL, 
    LAG(ITEM_ID,1,NULL) OVER (ORDER BY ITEM_ID ASC, DATE_COL ASC) AS LAST_ITEM_ID, 
    LAG(ITEM_ID,2,NULL) OVER (ORDER BY ITEM_ID ASC, DATE_COL ASC) AS LAST_ITEM_ID2, 
    LAG(TO_CHAR(DATE_COL,'DD-MON-YYYY'),1,NULL) OVER (ORDER BY ITEM_ID ASC, DATE_COL ASC) AS LAST_DATE, 
    LAG(TO_CHAR(DATE_COL,'DD-MON-YYYY'),2,NULL) OVER (ORDER BY ITEM_ID ASC, DATE_COL ASC) AS LAST_DATE2, 
    LAG(RESULT_COL,1,NULL) OVER (ORDER BY ITEM_ID ASC, DATE_COL ASC) AS LAST_RESULT, 
    LAG(RESULT_COL,2,NULL) OVER (ORDER BY ITEM_ID ASC, DATE_COL ASC) AS LAST_RESULT2 
    FROM 
    DATE_RESULT 
) 
WHERE 
    ITEM_ID = LAST_ITEM_ID 
    AND ITEM_ID = LAST_ITEM_ID2 
    AND TO_DATE(DATE_COL)-1 = TO_DATE(LAST_DATE) 
    AND TO_DATE(DATE_COL)-2 = TO_DATE(LAST_DATE2) 
    AND RESULT_COL = LAST_RESULT 
    AND RESULT_COL = LAST_RESULT2; 

查詢使用Oracle的LAG()函數從以前的行獲取值。因此,在此示例中,LAST_ITEM_ID是上一行中的項目標識,LAST_ITEM_ID是之前2行中的項目標識。

在WHERE子句中,我確保ITEM_ID匹配前兩個ITEM_ID並且RESULT_COL匹配前兩個RESULT_COL。我也確保最後兩個日期是連續的。

+0

抱歉沒有很好地描述我想要做什麼。這已經非常接近了。但是我正在尋找具有特定結果的項目,比如說'x'連續出現3次。這些日期可以是任何時間,除了'x'之外,只能有其他事件。滯後()似乎是正確的路要走。我會看看我能否提取這個意思。非常感謝! – 2014-09-30 12:30:59

1
SQL> WITH DATA AS(
    2 SELECT 1 ITEM_ID, TO_DATE('1.2.2014','DD.MM.YYYY') DT, 'A' RSLT FROM DUAL UNION ALL 
    3 SELECT 5,  TO_DATE('6.4.2014','DD.MM.YYYY') , 'B' RSLT FROM DUAL UNION ALL 
    4 SELECT 9,  TO_DATE('7.4.2014','DD.MM.YYYY') , 'A' RSLT FROM DUAL UNION ALL 
    5 SELECT 1,  TO_DATE('8.4.2014','DD.MM.YYYY') , 'A' RSLT FROM DUAL UNION ALL 
    6 SELECT 1,  TO_DATE('9.4.2014','DD.MM.YYYY') , 'A' RSLT FROM DUAL UNION ALL 
    7 SELECT 1,  TO_DATE('10.4.2014','DD.MM.YYYY') , 'A' RSLT FROM DUAL) 
    8 SELECT ITEM_ID FROM(
    9 SELECT A.*, ROW_NUMBER() OVER(PARTITION BY ITEM_ID ORDER BY RSLT) RN 
10 FROM DATA A) 
11 WHERE RN =3 
12/

    ITEM_ID 
---------- 
     1 

SQL> 
0

感謝用戶1578653我想通了。也許還有一個更優雅的方式做到這一點,但它在幾秒鐘內工作了50多萬條記錄:

SELECT ITEM_ID FROM(
    SELECT ITEM_ID, DATECOL, RESULT, 
    LAG(ITEM_ID,1,NULL) OVER (ORDER BY ITEM_ID ASC, DATECOL ASC) AS LASTITEM, 
    LAG(ITEM_ID,2,NULL) OVER (ORDER BY ITEM_ID ASC, DATECOL ASC) AS LASTITEM2, 
    LAG(RESULT,1,NULL) OVER (ORDER BY ITEM_ID ASC, DATECOL ASC) AS LASTCODE, 
    LAG(RESULT,2,NULL) OVER (ORDER BY ITEM_ID ASC, DATECOL ASC) AS LASTCODE2 
    FROM 
    RESULTTABLE 
    ) 
WHERE 
    ITEM_ID = LASTITEM 
    AND ITEM_ID = LASTITEM2 
    AND RESULT = 'A' 
    AND RESULT = LASTCODE 
    AND RESULT = LASTCODE2; 

我一直在尋找發生連續3次在這個例子中「A」的結果。

我很開心,謝謝!