2012-02-14 52 views
2

我想通過與以前的條目(對於該帳戶)進行比較來從表中檢索記錄。 請看下面的表格和數據。SQL:基於特定條件將行與前一行進行比較

在這一點放我就是想,

ID_NUM DELIVERY_TYPE 
100  2     
101  2 
102  2 

說明:我需要的, 100,因爲它是與DELIVERY_TYPE第一次出現是2(舊記錄有1) 101,因爲這是它第一次出現與DELIVERY_TYPE IS 2(舊記錄有3) 102,因爲只有一個用於此ID_NUM條目和DELIVERY_TYPE IS 2

我不需要 103因爲最近DELIVERY_TYPE IS 1即使它已經DELIVERY_TYPE爲2只 104因爲... e它有兩個或兩個以上的記錄DELIVERY_TYPE IS 2

任何機構都知道如何實現這個結果?

CREATE TABLE DEMO 
    (
    ID_NUM   NUMBER(10,0), 
    DELIVERY_TYPE NUMBER(2,0), 
    NAME   VARCHAR2(100), 
    CREATED_DATE DATE 
); 


INSERT INTO DEMO 
    (ID_NUM, DELIVERY_TYPE, CREATED_DATE) 
VALUES 
    (100, 2, TO_DATE('10-FEB-12 11:08:49 AM', 'DD-MON-RR HH:MI:SS AM')); 
INSERT INTO DEMO 
    (ID_NUM, DELIVERY_TYPE, CREATED_DATE) 
VALUES 
    (100, 1, TO_DATE('29-JAN-12 11:09:00 AM', 'DD-MON-RR HH:MI:SS AM')); 

INSERT INTO DEMO 
    (ID_NUM, DELIVERY_TYPE, CREATED_DATE) 
VALUES 
    (101, 2, TO_DATE('09-FEB-12 11:09:26 AM', 'DD-MON-RR HH:MI:SS AM')); 
INSERT INTO DEMO 
    (ID_NUM, DELIVERY_TYPE, CREATED_DATE) 
VALUES 
    (101, 3, TO_DATE('14-JAN-12 11:09:33 AM', 'DD-MON-RR HH:MI:SS AM')); 

INSERT INTO DEMO 
    (ID_NUM, DELIVERY_TYPE, CREATED_DATE) 
VALUES 
    (102, 2, TO_DATE('02-FEB-12 10:09:26 AM', 'DD-MON-RR HH:MI:SS AM')); 

INSERT INTO DEMO 
    (ID_NUM, DELIVERY_TYPE, CREATED_DATE) 
VALUES 
    (103, 1, TO_DATE('01-FEB-12 10:09:26 AM', 'DD-MON-RR HH:MI:SS AM')); 
INSERT INTO DEMO 
    (ID_NUM, DELIVERY_TYPE, CREATED_DATE) 
VALUES 
    (103, 2, TO_DATE('02-JAN-12 11:09:33 AM', 'DD-MON-RR HH:MI:SS AM')); 

INSERT INTO DEMO 
    (ID_NUM, DELIVERY_TYPE, CREATED_DATE) 
VALUES 
    (104, 2, TO_DATE('02-FEB-12 10:09:26 AM', 'DD-MON-RR HH:MI:SS AM')); 
INSERT INTO DEMO 
    (ID_NUM, DELIVERY_TYPE, CREATED_DATE) 
VALUES 
    (104, 2, TO_DATE('02-FEB-12 10:09:26 AM', 'DD-MON-RR HH:MI:SS AM')); 
+0

所以規則不是你所得到的最後交貨類型每個id_num。你能否解釋一下沒有返回id_num 103和104有點清楚的邏輯? – 2012-02-14 23:22:37

回答

1

可以使用ROW_NUMBER()函數通過對ID_NUM進行分區和按CREATED_DATE降序進行排序來隔離最新的行。然後確定多個DELIVERY_TYPE = 2的出現次數以過濾結果集:

SELECT ID_NUM, DELIVERY_TYPE 
FROM (SELECT ID_NUM, DELIVERY_TYPE, 
      ROW_NUMBER() OVER (PARTITION BY ID_NUM 
           ORDER BY CREATED_DATE DESC) AS RN 
     FROM DEMO) 
WHERE RN = 1 
AND DELIVERY_TYPE = 2 
MINUS 
SELECT ID_NUM, DELIVERY_TYPE 
FROM (SELECT ID_NUM, DELIVERY_TYPE, COUNT(*) AS REC_COUNT 
     FROM DEMO 
     WHERE DELIVERY_TYPE = 2 
     GROUP BY ID_NUM, DELIVERY_TYPE 
     HAVING COUNT(*) > 1) 

這將返回預期結果。

2

使用LAG功能。

如果您爲您的示例發佈一個小型表值而不是(/除了)插入語句,它可能會更容易。

1

該查詢會給你一個給定的輸入您想要的輸出雖然我不完全理解你的規則:

select ID_NUM, DELIVERY_TYPE 
    from ( select ID_NUM, DELIVERY_TYPE, CREATED_DATE 
       from DEMO 
      group by ID_NUM, DELIVERY_TYPE, CREATED_DATE 
      having count(*) = 1) CNT1 
    where CREATED_DATE = (select max(CREATED_DATE) 
          from DEMO D 
          where D.ID_NUM = CNT1.ID_NUM) 
     and DELIVERY_TYPE <> 1 
order by ID_NUM, DELIVERY_TYPE, CREATED_DATE 

如果你如果說會發生什麼擴大,一個ID_NUM只有一個條目,但它不是DELIVERY_TYPE = 1例如,那麼也許我可以更新。

1

以下查詢返回每個id_num一個記錄,其中最後delivery_type爲2和值2 delivery_type出現恰好一次:

SELECT DISTINCT id_num, last_delivery_type 
FROM (SELECT id_num, 
       FIRST_VALUE(delivery_type) 
        OVER (PARTITION BY id_num 
         ORDER BY created_date DESC) 
        AS last_delivery_type, 
       COUNT(CASE WHEN delivery_type = 2 
          THEN 2 ELSE NULL END) 
        OVER (PARTITION BY id_num) AS delivery_type_2_cnt 
     FROM demo) 
WHERE last_delivery_type = 2 AND delivery_type_2_cnt = 1 
相關問題