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
有两个不同的类别,即 Cat1
和 Cat2
。这是无效的。在这种情况下,我想用一些错误字符串更新 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_CATEGORY
和 MERGE 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
我需要一些帮助。
我有一个 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
有两个不同的类别,即 Cat1
和 Cat2
。这是无效的。在这种情况下,我想用一些错误字符串更新 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_CATEGORY
和 MERGE 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