2012-02-14 6 views
2

Я хотел получить записи из таблицы по сравнению с предыдущей записью (для этой учетной записи). См. Таблицу и данные ниже.SQL: сравнить строку с предыдущей строкой на основе определенного условия

В этом вне положенный я хотел есть,

ID_NUM DELIVERY_TYPE 
100  2     
101  2 
102  2 

Объяснение: Мне нужно, 100, потому что это его первое вхождение с DELIVERY_TYPE IS 2 (Старая запись имеет 1) 101, потому что это его первое вхождение с DELIVERY_TYPE IS 2 (Старая запись имеет 3) 102, потому что есть только одна запись для этого ID_NUM и DELIVERY_TYPE IS 2

Я НЕ НУЖНО 103, потому что недавний DELIVERY_TYPE IS 1 даже он DELIVERY_TYPE IS 2 104 becaus 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, яснее, пожалуйста? –

ответ

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 
Смежные вопросы