ORACLE:识别并更新无效的重复记录

ORACLE: Identify and update invalid duplicate records

我需要一些帮助。

我有一个 table 如下。

+---------------+------------------+---------------+-------+
|    ITEM_NO    | ITEM_DESCRIPTION | ITEM_CATEGORY | ERROR |
+---------------+------------------+---------------+-------+
| TestItem10001 | TestItem10001    | Cat1          |       |
| TestItem10001 | TestItem10001    | Cat2          |       |
| TestItem10002 | TestItem10002    | Cat3          |       |
| TestItem10002 | TestItem10002    | Cat3          |       |
| TestItem10003 | TestItem10003    | Cat3          |       |
+---------------+------------------+---------------+-------+

我的要求是:相同ITEM_NO不能有不同ITEM_CATEGORY。 所以在上面的 table 中,TestItem10001 有两个不同的类别,即 Cat1Cat2。这是无效的。在这种情况下,我想用一些错误字符串更新 ERROR 列,例如:

+---------------+------------------+---------------+------------------+
|    ITEM_NO    | ITEM_DESCRIPTION | ITEM_CATEGORY |      ERROR       |
+---------------+------------------+---------------+------------------+
| TestItem10001 | TestItem10001    | Cat1          |                  |
| TestItem10001 | TestItem10001    | Cat2          | INVALID CATEGORY |
| TestItem10002 | TestItem10002    | Cat3          |                  |
| TestItem10002 | TestItem10002    | Cat3          |                  |
| TestItem10003 | TestItem10003    | Cat3          |                  |
+---------------+------------------+---------------+------------------+

请建议如何以更清洁的方式实现这一点,因为实时 table 将有数百万条记录。

提前致谢。

编辑 1: 根据评论中的要求创建和插入。

CREATE TABLE STAGING_TABLE
(
    "ITEM_NO" VARCHAR2(1000 BYTE), 
    "ITEM_DESCRIPTION" VARCHAR2(1000 BYTE), 
    "ITEM_CATEGORY" VARCHAR2(1000 BYTE), 
    "ERROR" VARCHAR2(1000 BYTE)
);
Insert into STAGING_TABLE (ITEM_NO,ITEM_DESCRIPTION,ITEM_CATEGORY) values ('TestItem10001','TestItem10001','Cat1',null);
Insert into STAGING_TABLE (ITEM_NO,ITEM_DESCRIPTION,ITEM_CATEGORY) values ('TestItem10001','TestItem10001','Cat2',null);
Insert into STAGING_TABLE (ITEM_NO,ITEM_DESCRIPTION,ITEM_CATEGORY) values ('TestItem10002','TestItem10002','Cat3',null);
Insert into STAGING_TABLE (ITEM_NO,ITEM_DESCRIPTION,ITEM_CATEGORY) values ('TestItem10002','TestItem10002','Cat3',null);
Insert into STAGING_TABLE (ITEM_NO,ITEM_DESCRIPTION,ITEM_CATEGORY) values ('TestItem10003','TestItem10003','Cat3',null);

您可以使用以下SQL来达到您的目的

    select item_no,item_description,item_category,'INVALID CATEGORY' from (
    select count(item_no) over (partition by item_no order by item_category)item_cnt,
    count(item_no) over (partition by item_no,item_category order by item_no) 
    category_cnt,
    st.* from staging_table st)
    where item_cnt<> category_cnt

由于重复项的哪一行将被标记为无效并不重要,您可以使用此查询:

SELECT ITEM_NO, MIN(ITEM_CATEGORY) MIN_ITEM_CATEGORY
FROM STAGING_TABLE
GROUP BY ITEM_NO

其中 returns 每个 ITEM_NO 的最小 ITEM_CATEGORYMERGE INTO 语句:

MERGE INTO STAGING_TABLE s
USING (
  SELECT ITEM_NO, MIN(ITEM_CATEGORY) MIN_ITEM_CATEGORY
  FROM STAGING_TABLE
  GROUP BY ITEM_NO
) t
ON (t.ITEM_NO = s.ITEM_NO AND t.MIN_ITEM_CATEGORY <> s.ITEM_CATEGORY)
WHEN MATCHED THEN
UPDATE SET s.ERROR = 'INVALID CATEGORY'

参见demo
结果:

> ITEM_NO       | ITEM_DESCRIPTION | ITEM_CATEGORY | ERROR           
> :------------ | :--------------- | :------------ | :---------------
> TestItem10001 | TestItem10001    | Cat1          | null            
> TestItem10001 | TestItem10001    | Cat2          | INVALID CATEGORY
> TestItem10002 | TestItem10002    | Cat3          | null            
> TestItem10002 | TestItem10002    | Cat3          | null            
> TestItem10003 | TestItem10003    | Cat3          | null