查找缺失的对 (Oracle SQL)

Posted

技术标签:

【中文标题】查找缺失的对 (Oracle SQL)【英文标题】:Find missing pairs (Oracle SQL) 【发布时间】:2021-04-13 22:12:25 【问题描述】:

假设我有一个名为customer_accounts 的表,如下所示:

表:CUSTOMER_ACCOUNTS

+------------------+--------------+
| CUSTOMER_ID (PK) |  ACCOUNT_ID  | 
+------------------+--------------+
|        1         |          5   |
|        1         |          6   | 
|        1         |          8   | 
+------------------+--------------+

我还有另一个名为 distinct_account_pairs 的表,如下所示:

表:DISTINCT_ACCOUNT_PAIRS(之前)

+------------------+---------------+---------------+
| CUSTOMER_ID (PK) |  ACCOUNT_ID1  | ACCOUNT_ID2   |
+------------------+---------------+---------------+
|        1         |          6    |       5       |
+------------------+---------------+---------------+

如何使用每个 CUSTOMER_ID 的缺失对填充 distinct_account_pairs 表?在此示例中,distinct_account_pairs 中的 PK CUSTOMER_ID 1 缺少 5 和 8、6 和 8,因此之后应该看起来像这样。请注意 distinct_account_pairs 可能有 account_id1

表:DISTINCT_ACCOUNT_PAIRS(之后)

+------------------+---------------+---------------+
| CUSTOMER_ID (PK) |  ACCOUNT_ID1  | ACCOUNT_ID2   |
+------------------+---------------+---------------+
|        1         |          6    |       5       |
|        1         |          5    |       8       |
|        1         |          6    |       8       |
+------------------+---------------+---------------+

【问题讨论】:

我假设 PK 的意思是“主键”?您确实意识到,您在CUSTOMER_ACCOUNTS 中标记(PK)的列实际上不是该表中的“主键”吗?不可能 - 它有重复的值。 关于您的问题:因此,第二个表中已经存在的对必须保持原样(即使ACCOUNT_ID1 > ACCOUNT_ID2,但 missing 对都可以添加在所有情况下都使用ACCOUNT_ID1 < ACCOUNT_ID2?另外,您需要更改第二个表(可能通过INSERT 语句),而不仅仅是编写SELECT 查询以获得所需的结果? 【参考方案1】:

你可以用self join来做,不存在:

 create table CUSTOMER_ACCOUNTS ( CUSTOMER_ID int,  ACCOUNT_ID  int);

 insert into CUSTOMER_ACCOUNTS values(        1         ,          5   );
 insert into CUSTOMER_ACCOUNTS values(        1         ,          6   ); 
 insert into CUSTOMER_ACCOUNTS values(        1         ,          8   );

 create table DISTINCT_ACCOUNT_PAIRS ( CUSTOMER_ID int,  ACCOUNT_ID1  int, ACCOUNT_ID2   int);
 insert into DISTINCT_ACCOUNT_PAIRS values(        1         ,          6    ,       5       );

插入查询:

 insert into DISTINCT_ACCOUNT_PAIRS 
 select a.CUSTOMER_ID,a.ACCOUNT_ID,b.ACCOUNT_ID from CUSTOMER_ACCOUNTS a inner join CUSTOMER_ACCOUNTS b
 on a.CUSTOMER_ID = b.CUSTOMER_ID and a.ACCOUNT_ID < b.ACCOUNT_ID
 and not exists 
               (select 1 from DISTINCT_ACCOUNT_PAIRS d where d.CUSTOMER_ID=a.CUSTOMER_ID
               and ((d.ACCOUNT_ID1=a.ACCOUNT_ID and d.ACCOUNT_ID2=b.ACCOUNT_ID)
               or (d.ACCOUNT_ID1=b.ACCOUNT_ID and d.ACCOUNT_ID2=a.ACCOUNT_ID))
               );

查询:从 DISTINCT_ACCOUNT_PAIRS 中选择

 SELECT * FROM DISTINCT_ACCOUNT_PAIRS;

输出:

CUSTOMER_ID ACCOUNT_ID1 ACCOUNT_ID2
1 6 5
1 6 8
1 5 8

dbhere

【讨论】:

【参考方案2】:

您将生成所有对,然后比较它们:

select ca1.customer_id, ca1.account_id, ca2.account_id
from customer_accounts ca1 join
     customer_accounts ca2
     on ca1.customer_id = ca2.customer_id and
        ca1.account_id < ca2.account_id left join
     distinct_account_pairs dap
     on dap.customer_id = ca1.customer_id and
        dap.account_id1 in (ca1.account_id, ca2.account_id) and
        dap.account_id2 in (ca1.account_id, ca2.account_id) 
where dap.customer_id is null;
        

【讨论】:

以上是关于查找缺失的对 (Oracle SQL)的主要内容,如果未能解决你的问题,请参考以下文章

在表中查找缺失的序列

oracle执行SQL语句时报选项缺失或无效

oracle 数据库显示缺失右括号

ORA-00907: 缺失右括号问题整理解决

查找缺失行的 SQL 查询返回语法错误

SQL Server:查找缺失 ID 的有效方法