SQL: сравнить строку с предыдущей строкой на основе определенного условия - PullRequest
2 голосов
/ 15 февраля 2012

Я хотел получить записи из таблицы, сравнив их с предыдущей записью (для этой учетной записи). Пожалуйста, посмотрите таблицу и данные ниже.

В этом выходе я хотел,

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 равен 1, даже если он имеет DELIVERY_TYPE равен 2 104, потому что он имеет две или более записей с 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'));

Ответы [ 4 ]

2 голосов
/ 15 февраля 2012

используйте функцию LAG.

было бы проще, если бы вы опубликовали небольшую таблицу значений для вашего примера вместо (/ в дополнение к) ваших операторов вставки.

1 голос
/ 15 февраля 2012

Следующий запрос возвращает одну запись для каждого 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
1 голос
/ 15 февраля 2012

Вы можете использовать функцию 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)

Это вернет ожидаемые результаты.

1 голос
/ 15 февраля 2012

Этот запрос даст вам желаемый результат для данного ввода, хотя я не совсем понимаю ваши правила:

  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, возможно, я смогу обновить.

...