我对数据库工作还比较陌生,因此我可能使用了一些不正确的术语。请不要被误导。
假设我有三个表:项目表、客户表和连接这两个表的连接表。(这与我的实际用例无关,因此请忽略任何看似不合理的东西。我只是在强调一个抽象的例子。)
假设 Items 表有四条记录,即数字 1 到 4。假设 Customers 表有十条记录,即字母 A 到 J。假设这是连接表:
物品 | 顾客 |
---|---|
1 | A |
1 | C |
1 | H |
2 | A |
2 | H |
3 | A |
3 | C |
3 | H |
4 | C |
4 | 德 |
4 | 埃 |
通过此表的排序可以很容易地看出,它将项目映射到客户集,就像这样:
物品 | 客户集 |
---|---|
1 | {A、C、H} |
2 | {A,H} |
3 | {A、C、H} |
4 | {C、D、E} |
我正在寻找比较这些集合映射的方法。让 X 和 Y 为任意两个项目,让 J(X) 为 X 由连接表映射到的客户集。我希望能够回答以下问题:
- J(X) = J(Y) 吗?[外延的,所以不考虑顺序]
- J(X) 是 J(Y) 的子集吗?
- J(X) 是否部分重叠 J(Y)?如果是,它们的交点是多少?
从计算的角度来看,这些似乎都是非常基本的问题。我不相信没有办法做到这一点。如果在 Access 中不可能,但在其他系统中却可以,您能给我指明正确的方向吗?
答案1
假设你的表是t
。记住,我们可以考虑以下定义:
- item_1 是正在比较的项目
- customer_1 是被比较商品的客户
- item_2 是与 item_1 进行比较的项目
- customer_2 是与 item_1 进行比较的商品的客户
那么你可以这样做:
SELECT x.item AS item_1, x.customer AS customer_1, y.item AS item_2, y.customer AS customer_2
FROM t AS x
INNER JOIN t AS y ON x.item <> y.item AND x.customer = Y.customer
UNION ALL
SELECT DISTINCT x.item, x.customer, y.item, null
FROM t AS x
LEFT JOIN t AS y ON x.item <> y.item
AND NOT EXISTS (SELECT 1 FROM t AS z WHERE z.item = y.item AND z.customer = x.customer)
UNION ALL
SELECT DISTINCT y.item, NULL, x.item, x.customer
FROM t AS x
RIGHT JOIN t AS y ON x.item <> y.item
AND NOT EXISTS (SELECT 1 FROM t AS z WHERE z.item = y.item AND z.customer = x.customer)
ORDER BY item_1, item_2, customer_1;
该查询有三个部分。
第 1 部分 - 获取商品不同但客户相同的行
SELECT x.item AS item_1, x.customer AS customer_1, y.item AS item_2, y.customer AS customer_2
FROM t AS x
INNER JOIN t AS y ON x.item <> y.item AND x.customer = Y.customer
第 2 部分 - 获取 item 不同的行,并且 item_1 的客户在 item_2 的客户列表中不存在
SELECT DISTINCT x.item, x.customer, y.item, null
FROM t AS x
LEFT JOIN t AS y ON x.item <> y.item
AND NOT EXISTS (SELECT 1 FROM t AS z WHERE z.item = y.item AND z.customer = x.customer)
第 3 部分 - 获取 item 不同的行,并且 item_2 的客户在 item_1 的客户列表中不存在
SELECT DISTINCT y.item, NULL, x.item, x.customer
FROM t AS x
RIGHT JOIN t AS y ON x.item <> y.item
AND NOT EXISTS (SELECT 1 FROM t AS z WHERE z.item = y.item AND z.customer = x.customer)
考虑 item_1 = 1 的情况。目标是将项目 2 - 4 的每个客户集与项目 1 的客户集进行比较。结果如下(我已将其粘贴到 Excel 中,以便可以对其进行注释)
现在假设您使用该查询并将其保存为数据库中名为 [comparisons] 的视图,那么您可以执行如下操作(除其他操作外):
SELECT item_1,
item_2,
CASE WHEN COUNT(DISTINCT customer_1) = COUNT(DISTINCT customer_2)
THEN 'set is the same size' ELSE 'set is not the same size'
END AS set_size_comparison,
CASE WHEN SUM(CASE WHEN customer_1 IS NULL THEN 1 ELSE 0 END) <> 0
THEN 'item_2 has customers not present in item_1' ELSE 'item_1 entirely contains item_2'
END AS check_1,
CASE WHEN SUM(CASE WHEN customer_2 IS NULL THEN 1 ELSE 0 END) <> 0
THEN 'item_1 has customers not present in item_2' ELSE 'item_2 entirely contains item_1'
END AS check_2
FROM comparisons
WHERE item_1 = 1
GROUP BY item_1, item_2;
项目_1 | 项目_2 | 设置大小比较 | 检查1 | 检查2 |
---|---|---|---|---|
1 | 2 | 集合大小不同 | item_1 完全包含 item_2 | item_1 中有 item_2 中不存在的客户 |
1 | 3 | 集合大小相同 | item_1 完全包含 item_2 | item_2 完全包含 item_1 |
1 | 4 | 集合大小相同 | item_2 中有 item_1 中不存在的客户 | item_1 中有 item_2 中不存在的客户 |