如何在Oracle SQL数据库中查找相关行

时间:2019-02-19 03:36:16

标签: sql oracle duplicates

使用与此类似的表:

+-----------------+--------------------------+----------+
| CONTRACT_NUMBER | ORIGINAL_CONTRACT_NUMBER | CUST_ID| |
+-----------------+--------------------------+----------+
| 1               |                     0090 |      789 |
| 1-01            |                     0090 |      654 |
| 1-02            |                     0090 |      123 |
| 2               |                     0093 |      001 |
| 2 -01           |                     0093 |      001 |
| 3               |                     0094 |      666 |
| 4               |                     0095 |      999 |
| 4-01            |                     0095 |      888 |
| 5               |                     0096 |      002 |
| 5-01            |                     0096 |      002 |
| 6               |                     0097 |      555 |
+-----------------+--------------------------+----------+

我正在尝试对没有重复(即contract_number 3和6)且有重复但具有相同cust_id(即contract_numbers 2、2-01和5、5-01)的所有记录进行排序,其中仅有的剩余合同类型具有多个具有相同合同编号但具有不同cust_id的条目(即合同1,1-01、1-02和4,4-01)。我需要全部为sql,因为我需要评估超过140k条记录

Oracle SQL 11g

我的代码没有任何进展。

预期结果将是这样

+-----------------+--------------------------+---------+
| CONTRACT_NUMBER | ORIGINAL_CONTRACT_NUMBER | CUST_ID |
+-----------------+--------------------------+---------+
| 1               |                     0090 |     789 |
| 1-01            |                     0090 |     654 |
| 1-02            |                     0090 |     123 |
| 4               |                     0095 |     999 |
| 4-01            |                     0095 |     888 |
+-----------------+--------------------------+---------+

4 个答案:

答案 0 :(得分:2)

使用db<>fiddle在线进行测试:

WITH
  t AS (
    SELECT '1' AS contract_number, '0090' AS original_contract_number,
           '789' AS cust_id FROM dual UNION ALL
    SELECT '1-01',  '0090', '654' FROM dual UNION ALL
    SELECT '1-02',  '0090', '123' FROM dual UNION ALL
    SELECT '2',     '0093', '001' FROM dual UNION ALL
    SELECT '2 -01', '0093', '001' FROM dual UNION ALL
    SELECT '3',     '0094', '666' FROM dual UNION ALL
    SELECT '4',     '0095', '999' FROM dual UNION ALL
    SELECT '4-01',  '0095', '888' FROM dual UNION ALL
    SELECT '5',     '0096', '002' FROM dual UNION ALL
    SELECT '5-01',  '0096', '002' FROM dual UNION ALL
    SELECT '6',     '0097', '555' FROM dual
  ),
  a AS (
    SELECT t.*,
      COUNT(DISTINCT cust_id) OVER (PARTITION BY original_contract_number) q
    FROM t
  )
SELECT
  contract_number, original_contract_number, cust_id
FROM a
WHERE q > 1;

输出:

+-----------------+--------------------------+---------+
| CONTRACT_NUMBER | ORIGINAL_CONTRACT_NUMBER | CUST_ID |
+-----------------+--------------------------+---------+
| 1-02            |                     0090 |     123 |
| 1-01            |                     0090 |     654 |
| 1               |                     0090 |     789 |
| 4-01            |                     0095 |     888 |
| 4               |                     0095 |     999 |
+-----------------+--------------------------+---------+

答案 1 :(得分:0)

正如您提到的那样,您希望输出带有唯一ID的合同编号重复的合同,那么您可以利用存在来找出您的合同编号具有多个唯一ID的情况,并以此方式获得输出。

 with cte as (
 select '1'     as Contract_No, '0090' as  ORIGINAL_CONTRACT_NUMBER, '789' as Cust_ID 
 from dual union all 
 select '1-01'  as Contract_No, '0090' as  ORIGINAL_CONTRACT_NUMBER, '654' as Cust_ID 
from dual union all 
select '1-02'  as Contract_No, '0090' as  ORIGINAL_CONTRACT_NUMBER, '123' as Cust_ID 
from dual union all 
select '2'     as Contract_No, '0093' as  ORIGINAL_CONTRACT_NUMBER, '001' as Cust_ID 
from dual union all 
 select '2 -01' as Contract_No, '0093' as  ORIGINAL_CONTRACT_NUMBER, '001' as Cust_ID 
 from dual union all 
 select '3'     as Contract_No, '0094' as  ORIGINAL_CONTRACT_NUMBER, '666' as Cust_ID 
 from dual union all 
 select '4'     as Contract_No, '0095' as  ORIGINAL_CONTRACT_NUMBER, '999' as Cust_ID 
 from dual union all 
  select '4-01'  as Contract_No, '0095' as  ORIGINAL_CONTRACT_NUMBER, '888' as 
  Cust_ID from dual union all 
  select '5'     as Contract_No, '0096' as  ORIGINAL_CONTRACT_NUMBER, '002' as 
  Cust_ID from dual union all 
  select '5-01'  as Contract_No, '0096' as  ORIGINAL_CONTRACT_NUMBER, '002' as 
  Cust_ID from dual union all 
  select '6'     as Contract_No, '0097' as  ORIGINAL_CONTRACT_NUMBER, '555' as 
  Cust_ID from dual) 

查询:

 select * from cte  co 
 where   exists (select c1.ORIGINAL_CONTRACT_NUMBER,   count(distinct c1.cust_ID) 
 DifferentID  from cte c1 
             where c1.ORIGINAL_CONTRACT_NUMBER = co.ORIGINAL_CONTRACT_NUMBER 
              group by c1.ORIGINAL_CONTRACT_NUMBER
              having count(distinct c1.cust_ID) > 1) ; 

输出:

CONTRACT_NO ORIGINAL_CONTRACT_NUMBER    CUST_ID
       1                    0090        789
       1-01                 0090        654
       1-02                 0090        123
       4                     0095       999
       4-01                  0095       888

答案 2 :(得分:0)

下面是一种方法-

select * from MyTable where ORIGINAL_CONTRACT_NUMBER in (select
ORIGINAL_CONTRACT_NUMBER from MyTable group by ORIGINAL_CONTRACT_NUMBER having count(distinct(cust_id))>1)

希望这会有所帮助

答案 3 :(得分:0)

尝试一下...

SELECT
        A.CONTRACT_NUMBER
      , A.ORIGINAL_CONTRACT_NUMBER
      , A.CUST_ID
FROM
        CONTRACT_TABLE A
        INNER JOIN
                (
                        SELECT
                                CONTRACT_NUMBER
                        FROM
                                CONTRACT_TABLE
                        GROUP BY
                                CONTRACT_NUMBER
                        HAVING
                                COUNT(DISTINCT CUST_ID) > 1
                )
                B
                ON
                        A.CONTRACT_NUMBER = B.CONTRACT_NUMBER
ORDER BY
        A.CONTRACT_NUMBER