这种类型的查询的名称是什么,一个有效的例子是什么?

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。

这种类型的查询是否有名称,最有效的方法是什么?

ype*_*eᵀᴹ 8

您正在解决的问题称为关系除法,有两个变体,“带余数的除法”“精确除法”(符合您的描述)。

另见这篇文章:我们所持的分裂:关系分裂的 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)

其中,@n2在这种情况下,产品在您的支票数量。

SQL-Fiddle测试。