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;