如果在 table 中发现重复数据(不是重复记录),则抛出错误

Throw error , if duplicate data (not duplicate records) found in a table

我有一个 table,其中包含有关产品的信息,我需要检查重复记录并抛出错误。有两列,product key 和 product value,其中 product value 包含分号分隔和正常值。示例数据如下。 (无限制)

source_id |Product_key | Product_value
-----------------------------------------------------------
     1      xzy         PRODUCT_TAG=SCENT;CODE=123;PRICE=234
     1      xhmr          POWDER
     1      abc           PRODUCT_TAG=COMB;CODE=123;PRICE=234
     1      xhmr          OIL
     1      zrmt          123

现在我必须检查是否有任何两行具有相同的 product_key 和 product_tag 值,如果 product_key 是 xhmr,那么应该考虑 product_value作为 product_tag 值。我写的查询如下


select source_id, PRODUCT_KEY, rec , (case when  instr(rec,'PRODUCT_TAG')<>0 THEN regexp_substr(TRIM(rec), '[^=]+', 1,2)
ELSE rec
end) as PRODUCT_TAG
from 
(select source_id,PRODUCT_KEY ,regexp_substr(TRIM(PRODUCT_VALUE), '[^;]+', 1,LEVEL) AS rec from products 
 connect by  regexp_substr(TRIM(PRODUCT_VALUE), '[^;]+', 1,LEVEL) is not null
    AND prior source_id = source_id
   AND PRIOR SYS_GUID() IS NOT NULL) where instr(rec,'PRODUCT_TAG')<>0 or PRODUCT_KEY in('xhmr');

输出

source_id |Product_key | Product_value
-----------------------------------------------------------
     1      xzy           SCENT
     1      xhmr          POWDER
     1      abc           COMB
     1      xhmr          OIL

之后,我将对所有行和所有不同的行进行计数。如果两个计数不相等,那么抛出 error.I 就是想知道,是否所有这些都可以以简洁的方式完成。

我想你可能会做以下事情

  • 获取主查询并放入 with 子句
  • 然后你可以根据需要多次操作它

你可以这样写:

更新

  with main_query 
    as ( 
    select source_id, PRODUCT_KEY, rec , (case when  instr(rec,'PRODUCT_TAG')<>0 THEN regexp_substr(TRIM(rec), '[^=]+', 1,2)
    ELSE rec
    end) as PRODUCT_TAG
    from 
    (select source_id,PRODUCT_KEY ,regexp_substr(TRIM(PRODUCT_VALUE), '[^;]+', 1,LEVEL) AS rec from products 
     connect by  regexp_substr(TRIM(PRODUCT_VALUE), '[^;]+', 1,LEVEL) is not null
        AND prior source_id = source_id
       AND PRIOR SYS_GUID() IS NOT NULL) where instr(rec,'PRODUCT_TAG')<>0 or PRODUCT_KEY in('xhmr')
    ) 
    select 
    case when total_value = tot_dist then 'OK' -- whatever you want here
    else 'ERROR' -- whatever you want here
    end as result
    from 
    (  ( select count(*) as total_value  from main_query ) ,
       ( select count(*) as total_dist  from ( select distinct * from main_query ) ) 
    )

以我为例

 SQL> desc my_test
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 C1                                                 NUMBER
 C2                                                 NUMBER

SQL> select * from my_test ;

        C1         C2
---------- ----------
         1          1
         1          1
         2          2

SQL>  with main_query as ( select c1 , c2 from my_test )
  select a , b
 from
 ( select count(*) as a  from main_query ) ,
 ( select count(*) as b  from ( select distinct * from main_query ) )
 /  2    3    4    5    6

         A          B
---------- ----------
         3          2

 SQL>  with main_query as ( select c1 , c2 from my_test )
  select case when a = b then 'OK' else 'ERROR' end as result
 from
 ( select count(*) as a  from main_query ) ,
 ( select count(*) as b  from ( select distinct * from main_query ) )
/

RESUL
-----
ERROR