在只有部分值匹配的情况下进行1对1多字段SQL联接
我试图建立一个表,将作为一个转换图表使用。我的目标是在多个字段(在我的例子中是8个字段)上使用这个转换表进行简单的连接,并得到一个结果。我将尽量简化示例,因为原始图表是一个40x10矩阵 假设我有这两个(我知道它们没有多大意义,设计也不好,但它们只是示例): 转换图应该是这样的:在只有部分值匹配的情况下进行1对1多字段SQL联接,sql,postgresql,Sql,Postgresql,我试图建立一个表,将作为一个转换图表使用。我的目标是在多个字段(在我的例子中是8个字段)上使用这个转换表进行简单的连接,并得到一个结果。我将尽量简化示例,因为原始图表是一个40x10矩阵 假设我有这两个(我知道它们没有多大意义,设计也不好,但它们只是示例): 转换图应该是这样的: | supply | customer_id | product_id | size | purchase_type | |--------|--------------|------------|-----
| supply | customer_id | product_id | size | purchase_type |
|--------|--------------|------------|----------|---------------|
| 100 | 1 | anything | anything | online |
| 101 | 1 | anything | anything | offline |
| 102 | other than 1 | anything | anything | online |
| 103 | 1 | 5 | XXL | online |
主要目标是通过执行以下操作简单地进行连接,从而获得准确的供应值:
选择供应
从采购p
在scc上加入供应转换图表
p、 客户id=scc.customer\u id和
p、 产品标识=专用条款产品标识和
p、 尺寸=scc.尺寸和
p、 采购类型=专用条款采购类型;
假设这些是采购
表上的记录:
| customer_id | product_id | size | purchase_type |
|-------------|------------|------|---------------|
| 1 | 3 | M | online |
| 1 | 5 | S | offline |
| 12345 | 4 | XL | online |
| 1 | 5 | XXL | online |
| 4353 | null | M | online |
我希望第一条记录的供应值为101
,第二条记录的供应值为102
,第三条记录的供应值为102
,第四条记录的供应值为103
,第五条记录的供应值为102
。但是,据我所知,SQL无法对所有这些记录执行正确的联接,除了第四个记录,它与supply\u conversion\u chart
表上的supply103
完全匹配。我不知道当一些字段不完全匹配时,是否可以首先使用多个字段进行连接
我的方法可能是错误的,有更好的方法来达到我想要达到的结果,但我甚至不知道从哪里开始。我该怎么办?
原始图表比提供的示例大得多,我将在8个不同的字段上进行连接。您的方法是横向连接:
select p.*, scc.*
from purchases p left join lateral
(select scc.*
from supply_conversion_chart scc
where (scc.customer_id = p.customer_id or scc.customer_id is null) and
(scc.product_id = p.product_id or scc. product_id is null) and
(scc.size = p.size or scc.size is null) and
(scc.purchase_type = p.purchase_type or scc.purchase_type is null)
order by ( (scc.customer_id = p.customer_id)::int +
(scc.product_id = p.product_id)::int
(scc.size = p.size)::int
(scc.purchase_type = p.purchase_type)::int
) desc
limit 1
) scc;
注意:这表示“一切”为NULL
。对于“除1以外的客户”,它没有特殊的逻辑。然而,它确实向您展示了如何基本上实现您正在尝试做的事情
| customer_id | product_id | size | purchase_type |
|-------------|------------|------|---------------|
| 1 | 3 | M | online |
| 1 | 5 | S | offline |
| 12345 | 4 | XL | online |
| 1 | 5 | XXL | online |
| 4353 | null | M | online |
select p.*, scc.*
from purchases p left join lateral
(select scc.*
from supply_conversion_chart scc
where (scc.customer_id = p.customer_id or scc.customer_id is null) and
(scc.product_id = p.product_id or scc. product_id is null) and
(scc.size = p.size or scc.size is null) and
(scc.purchase_type = p.purchase_type or scc.purchase_type is null)
order by ( (scc.customer_id = p.customer_id)::int +
(scc.product_id = p.product_id)::int
(scc.size = p.size)::int
(scc.purchase_type = p.purchase_type)::int
) desc
limit 1
) scc;