首页 > 解决方案 > 嵌套相交

问题描述

我有一张出售物品的表格,其中包含 customer_id 和 item_name。我需要创建一个新表来获取包含 customer_a_id、customer_b_id、intersected_items_count 的相交项目的客户。

我写了一个带有游标和嵌套 for 循环的 PL/SQL 过程来执行这个操作,但是如果我有 100 万客户,这意味着 1m * 1m 循环怎么办?

我的问题是:是否有任何用于嵌套相交的 sql 方法(将所有行与表中的所有行相交)

我的桌子是这样的:

customer_id   item
1              Meat 
1              Rice 
2              Meat
2              Soups 
3              Pasta 

要求的输出:

customer_a_id customer_b_id intersected_items
1              2             1
1              3             0
2              1             1
2              3             0
3              1             0
3              2             0

标签: sqloracleplsql

解决方案


我会使用cross joinand left joins 来做到这一点:

select c1.customer_id, c2.customer_id, count(t2.item) as num_intersected_items
from (select distinct customer_id from t) c1 cross join
     (select distinct customer_id from t) c2 left join
     t t1
     on t1.customer_id = c1.customer_id left join
     t t2
     on t2.customer_id = c2.customer_id and t2.item = t1.item and
where c1.customer_id <> c2.customer_id
group by c1.customer_id, c2.customer_id;

此版本使您可以控制客户 ID——它们可能来自不同的表并包括没有项目的客户。

left join如果所有项目都来自同一个表,则结果等效于 a :

select t1.customer_id, t2.customer_id, count(t2.item) as num_intersected_items
from t t1 left join
     t t2
     on t1.item = t2.item 
where t1.customer_id <> t2.customer_id
group by c1.customer_id, c2.customer_id;

推荐阅读