2

我想通过与以前的条目(针对该帐户)进行比较来从表中检索记录。请看下面的表格和数据。

在这个输出中,我想要的是,

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 为 2

我不需要 103,因为最近的 DELIVERY_TYPE 是 1,即使它有 DELIVERY_TYPE 是 2 104,因为它有两条或更多条 DELIVERY_TYPE 是 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

4 回答 4

2

使用 LAG 函数。

如果您为您的示例发布一个小值表而不是(/除了)您的插入语句,它可能会更容易。

于 2012-02-14T23:19:32.277 回答
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  

如果您扩展如果例如 anID_NUM只有一个条目但它不是DELIVERY_TYPE= 1 时会发生什么,那么也许我可以更新。

于 2012-02-14T23:32:58.010 回答
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)

这将返回预期的结果。

于 2012-02-15T02:33:53.583 回答
1

以下查询为id_num最后一个delivery_type为 2 且值 2delivery_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
于 2012-02-15T16:16:17.300 回答