ORACLE: выявить и обновить недопустимые дубликаты записей - PullRequest
0 голосов
/ 19 апреля 2020

Мне нужна помощь.

У меня есть таблица, как показано ниже.

+---------------+------------------+---------------+-------+
|    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 , Таким образом, в приведенной выше таблице 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          |                  |
+---------------+------------------+---------------+------------------+

Пожалуйста, предложите, как этого можно достичь более чистым способом с менее дорогим подходом, поскольку таблица реального времени будет иметь миллионы записей.

Заранее спасибо.

РЕДАКТИРОВАТЬ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);

Ответы [ 2 ]

2 голосов
/ 19 апреля 2020

Поскольку не имеет значения, какая строка дубликатов будет помечена как недействительная, вы можете использовать этот запрос:

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

, который возвращает минимальное значение ITEM_CATEGORY для каждого ITEM_NO с 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'

См. демо . Результаты:

> 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   
1 голос
/ 19 апреля 2020

Вы можете использовать ниже 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
...