Nei*_*gan 4 performance query-performance
目的是找到父母,因为它是孩子。例如,假设您有一个营销包(又名“组合”),并希望根据其中的产品进行匹配。示例表/数据:
create table marketing_package_product (
package_id int not null references marketing_package(id),
product_id int not null references product(id),
primary key (package_id, product_id)
);
insert into marketing_package_product values
(1,1),
(1,2),
(1,3),
(2,1),
(2,5);
Run Code Online (Sandbox Code Playgroud)
给定产品 1,2,3,我想获得 marketing_package 1。但只给定产品 1,2,我不想要 marketing_package 1。
这种类型的查询是否有名称,最有效的方法是什么?
您正在解决的问题称为关系除法,有两个变体,“带余数的除法”和“精确除法”(符合您的描述)。
另见这篇文章:我们所持的分裂:关系分裂的 SQL
StackOverflow 上的这个问题:How to filter SQL results in a has-many-through Relations有几种方法可以解决它和 Postgres 的基准测试,但它不是针对确切的变化,仅针对"Division with Remainder"。查询将是相似的,但必须为确切的变化添加额外的检查/条件。
解决此问题的一种方法(太多)是将表与“产品”一样多次自连接,然后进行额外检查,以便只保留包含这些产品的包):
SELECT m1.package_id
FROM marketing_package_product AS m1
JOIN marketing_package_product AS m2
ON m2.package_id = m1.package_id
WHERE m1.product_id = 1
AND m2.product_id = 2
AND NOT EXISTS
( SELECT *
FROM marketing_package_product AS x
WHERE x.package_id = m1.package_id
AND x.product_id NOT IN (1,2)
) ;
Run Code Online (Sandbox Code Playgroud)
另一个是 toGROUP BY
然后两个HAVING
条件,一个用于除法,另一个用于“精确性”:
SELECT m.package_id
FROM marketing_package_product AS m
GROUP BY m.package_id
HAVING COUNT(CASE WHEN m.product_id IN (1,2) THEN 1 END) = @n
AND COUNT(*) = @n ;
Run Code Online (Sandbox Code Playgroud)
其中,@n
将2
在这种情况下,产品在您的支票数量。
在SQL-Fiddle测试。