如何使用多个近似匹配执行复杂的SQL连接并仅返回第一个匹配
我正在尝试在SQL中执行左连接,其中我需要检查多个匹配条件,并且在对右表执行某种排序操作后,只保留右表中的第一个匹配项 下面是我的左表。 没有空值 日期 顾客 商店 产品 顾客满意度分数 1/1/2020 C1 S1 P1 2. 1/2/2020 C2 S1 P2 8. 1/5/2020 C3 S2 P1 6. 1/6/2020 补体第四成份 S2 P2 10 1/7/2020 C1 S2 P3 2. 1/8/2020 C2 S2 P4 4. 使用和应用:如何使用多个近似匹配执行复杂的SQL连接并仅返回第一个匹配,sql,postgresql,join,Sql,Postgresql,Join,我正在尝试在SQL中执行左连接,其中我需要检查多个匹配条件,并且在对右表执行某种排序操作后,只保留右表中的第一个匹配项 下面是我的左表。 没有空值 日期 顾客 商店 产品 顾客满意度分数 1/1/2020 C1 S1 P1 2. 1/2/2020 C2 S1 P2 8. 1/5/2020 C3 S2 P1 6. 1/6/2020 补体第四成份 S2 P2 10 1/7/2020 C1 S2 P3 2. 1/8/2020 C2 S2 P4 4. 使用和应用: 最后,我能够解决它如下。感谢@iamd
最后,我能够解决它如下。感谢@iamdave的评论
SELECT Date, Customer, Shop, Product, Customer_Score, Min_Customer_Score, Percent_Discount
FROM
(
SELECT left_table.*, right_table.Percent_Discount, right_table.Min_Customer_Score
, ROW_NUMBER() OVER (
PARTITION BY left_table.Date, left_table.Customer, left_table.Shop, left_table.Product
ORDER BY right_table.Product DESC right_table.Min_Customer_Score ASC) as row_num
LEFT JOIN right_table
ON left_table.Date >= right_table.Valid_From
AND left_table.Date <= right_table.Valid_To
AND left_table.Shop = right_table.Shop
AND (left_table.Product = right_table.Product OR right_table.Product is NULL)
AND left_table.Customer_Score >= right_table.Min_Customer_Score
) as sub_query
WHERE row_num = 1
在这里使用row_number是正确的方法。按照您在问题中概述的方式进行左连接,在该选择中包括行号,然后筛选行号=1的行号。您的分区依据是您只想从中返回一行的一组值,order by确定该分区中的行顺序。尝试编写此脚本,并在问题中添加您尝试过的内容。谢谢@iamdave,我按照您的建议进行了尝试,并在问题中添加了代码谢谢。这种方法有效。不过我有点担心我的表现,因为我左边的桌子很大。这会对左表中的每一行进行单独的数据库查询吗?@ArjunAriyil我有点担心性能-您是否对数据进行了两个查询的测试以进行比较?如果没有,就这样做,并使用性能最好的。@ArjunAriyil。你必须浏览左表的所有行。正确的表格可能对性能有更大的影响。
SELECT Date, Customer, Shop, Product, Customer_Score, Min_Customer_Score, Percent_Discount
FROM
(
SELECT left_table.*, right_table.Percent_Discount, right_table.Min_Customer_Score
, ROW_NUMBER() OVER (
PARTITION BY left_table.Date, left_table.Customer, left_table.Shop, left_table.Product
ORDER BY right_table.Product DESC right_table.Min_Customer_Score ASC) as row_num
LEFT JOIN right_table
ON left_table.Date >= right_table.Valid_From
AND left_table.Date <= right_table.Valid_To
AND left_table.Shop = right_table.Shop
AND (left_table.Product = right_table.Product OR right_table.Product is NULL)
AND left_table.Customer_Score >= right_table.Min_Customer_Score
) as sub_query
WHERE row_num = 1