oracle CASE WHEN语句中如何查找重复记录
How to find duplicate records in oracle CASE WHEN Statement
我有两个 table,如下所示。 TABLEA 和 tableTABLEB。我们在 TRANS_ID 上进行外部连接并比较两个 tables.
我想得到result中所示的结果。我们仅检查 TABLEA 中的重复项(即基于 TABLEA.TRANS_ID)。
TABLEA
+------+----------+-------+--+-------------+
| UUID | TRANS_ID | NAME | | PHONENUMBER |
+------+----------+-------+--+-------------+
| 123 | 7928 | SCOTT | | 87482837849 |
| 123 | 7928 | SCOTT | | 87482837849 |
| 489 | 7493 | TOM | | 79274778397 |
| 827 | 7920 | DAVID | | 23794928749 |
| 324 | 8472 | PAT | | 87927478839 |
+------+----------+-------+--+-------------+
TABLEB
+----------+----------+--------+-------------+
| BATCH_ID | TRANS_ID | SENDER | PHONENUMBER |
+----------+----------+--------+-------------+
| 823784 | 7438 | LSK | 84748394092 |
| 793847 | 7493 | KLI | 79274778397 |
| 748738 | 7920 | ISL | 74892890487 |
+----------+----------+--------+-------------+
RESULT
+----------+-------------+-------------------------+
| TRANS_ID | PHONENUMBER | STATUS |
+----------+-------------+-------------------------+
| 7928 | 87482837849 | DUPLICATE RECORD |
| 7928 | 87482837849 | NOT IN TABLEB |
| 7438 | 84748394092 | NOT IN TABLEA |
| 7920 | 23794928749 | PHONENUMBER MISMATCH |
| 8472 | 87927478839 | NOT IN TABLEB |
+----------+-------------+-------------------------+
我尝试使用以下 case when 语句。除了提取重复项外,我涵盖了所有场景。当TABLEA中有重复记录而TABLEB中不存在时,第一条记录应为'NOT IN TABLEB',后续记录应为'DUPLICATE RECORD'
CASE
WHEN TABLEA.TRANS_ID is null THEN 'NOT IN TABLEA'
WHEN TABLEB.TRANS_ID is null THEN 'NOT IN TABLEB'
WHEN decode(TABLEA.PHONENUMBER,ALRAJHI_TABLEB.PHONENUMBER,1,0)=0 THEN 'PHONENUMBER MISMATCH'
END
这是一种方法:
WITH x
AS (SELECT ROW_NUMBER()
OVER (
PARTITION BY CASE WHEN a.trans_id IS NULL THEN b.trans_id ELSE a.trans_id END
ORDER BY CASE WHEN a.trans_id IS NULL THEN b.trans_id ELSE a.trans_id END) AS rn,
CASE WHEN a.trans_id IS NULL THEN b.trans_id ELSE a.trans_id END AS trans_id,
CASE WHEN a.trans_id IS NULL THEN b.phonenumber ELSE a.phonenumber END AS phonenumber,
CASE
WHEN a.trans_id IS NULL THEN 'NOT IN TABLEA'
WHEN b.trans_id IS NULL THEN 'NOT IN TABLEB'
WHEN DECODE(a.phonenumber, b.phonenumber, 1, 0) = 0 THEN 'PHONENUMBER MISMATCH'
END AS status
FROM tablea a
FULL OUTER JOIN tableb b
ON a.trans_id = b.trans_id),
y AS (
SELECT trans_id,
phonenumber,
CASE WHEN rn > 1 THEN 'DUPLICATE RECORD' ELSE status END AS status
FROM x)
SELECT * FROM y
WHERE status IS NOT NULL -- Exclude TableA records that are (presumably) OK
编辑:调整后的查询使用第二个 CTE (y) 作为状态的 NOT NULL 过滤器正在删除 ROW_NUMBER() 检查所需的行。
我想我会使用 union all
来从第一个 table:
中引入重复项
select trans_id, coalesce(ta.phonenumber, tb.phonenumber) as phonenumber,
(case when ta.phonenumber is null then 'NOT IN TABLEA'
when tb.phonenumber is null then 'NOT IN TABLEB'
else 'PHONENUMBER MISMATCH'
end) as status
from (select distinct trans_id, phonenumber
from tablea ta
) ta full join
tableb tb
using (trans_id)
where ta.phonenumber is null or tb.phonenumber is null or
ta.phonenumber <> tb.phonenumber
union all
select trans_id, phonenumber, 'DUPLICATE RECORD'
from tablea
group by trans_id, phonenumber
having count(*) >= 2;
我有两个 table,如下所示。 TABLEA 和 tableTABLEB。我们在 TRANS_ID 上进行外部连接并比较两个 tables.
我想得到result中所示的结果。我们仅检查 TABLEA 中的重复项(即基于 TABLEA.TRANS_ID)。
TABLEA
+------+----------+-------+--+-------------+
| UUID | TRANS_ID | NAME | | PHONENUMBER |
+------+----------+-------+--+-------------+
| 123 | 7928 | SCOTT | | 87482837849 |
| 123 | 7928 | SCOTT | | 87482837849 |
| 489 | 7493 | TOM | | 79274778397 |
| 827 | 7920 | DAVID | | 23794928749 |
| 324 | 8472 | PAT | | 87927478839 |
+------+----------+-------+--+-------------+
TABLEB
+----------+----------+--------+-------------+
| BATCH_ID | TRANS_ID | SENDER | PHONENUMBER |
+----------+----------+--------+-------------+
| 823784 | 7438 | LSK | 84748394092 |
| 793847 | 7493 | KLI | 79274778397 |
| 748738 | 7920 | ISL | 74892890487 |
+----------+----------+--------+-------------+
RESULT
+----------+-------------+-------------------------+
| TRANS_ID | PHONENUMBER | STATUS |
+----------+-------------+-------------------------+
| 7928 | 87482837849 | DUPLICATE RECORD |
| 7928 | 87482837849 | NOT IN TABLEB |
| 7438 | 84748394092 | NOT IN TABLEA |
| 7920 | 23794928749 | PHONENUMBER MISMATCH |
| 8472 | 87927478839 | NOT IN TABLEB |
+----------+-------------+-------------------------+
我尝试使用以下 case when 语句。除了提取重复项外,我涵盖了所有场景。当TABLEA中有重复记录而TABLEB中不存在时,第一条记录应为'NOT IN TABLEB',后续记录应为'DUPLICATE RECORD'
CASE
WHEN TABLEA.TRANS_ID is null THEN 'NOT IN TABLEA'
WHEN TABLEB.TRANS_ID is null THEN 'NOT IN TABLEB'
WHEN decode(TABLEA.PHONENUMBER,ALRAJHI_TABLEB.PHONENUMBER,1,0)=0 THEN 'PHONENUMBER MISMATCH'
END
这是一种方法:
WITH x
AS (SELECT ROW_NUMBER()
OVER (
PARTITION BY CASE WHEN a.trans_id IS NULL THEN b.trans_id ELSE a.trans_id END
ORDER BY CASE WHEN a.trans_id IS NULL THEN b.trans_id ELSE a.trans_id END) AS rn,
CASE WHEN a.trans_id IS NULL THEN b.trans_id ELSE a.trans_id END AS trans_id,
CASE WHEN a.trans_id IS NULL THEN b.phonenumber ELSE a.phonenumber END AS phonenumber,
CASE
WHEN a.trans_id IS NULL THEN 'NOT IN TABLEA'
WHEN b.trans_id IS NULL THEN 'NOT IN TABLEB'
WHEN DECODE(a.phonenumber, b.phonenumber, 1, 0) = 0 THEN 'PHONENUMBER MISMATCH'
END AS status
FROM tablea a
FULL OUTER JOIN tableb b
ON a.trans_id = b.trans_id),
y AS (
SELECT trans_id,
phonenumber,
CASE WHEN rn > 1 THEN 'DUPLICATE RECORD' ELSE status END AS status
FROM x)
SELECT * FROM y
WHERE status IS NOT NULL -- Exclude TableA records that are (presumably) OK
编辑:调整后的查询使用第二个 CTE (y) 作为状态的 NOT NULL 过滤器正在删除 ROW_NUMBER() 检查所需的行。
我想我会使用 union all
来从第一个 table:
select trans_id, coalesce(ta.phonenumber, tb.phonenumber) as phonenumber,
(case when ta.phonenumber is null then 'NOT IN TABLEA'
when tb.phonenumber is null then 'NOT IN TABLEB'
else 'PHONENUMBER MISMATCH'
end) as status
from (select distinct trans_id, phonenumber
from tablea ta
) ta full join
tableb tb
using (trans_id)
where ta.phonenumber is null or tb.phonenumber is null or
ta.phonenumber <> tb.phonenumber
union all
select trans_id, phonenumber, 'DUPLICATE RECORD'
from tablea
group by trans_id, phonenumber
having count(*) >= 2;