查找缺失的对 (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 |
db
【讨论】:
【参考方案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)的主要内容,如果未能解决你的问题,请参考以下文章