有两个表:

Packages

id     name
1      red
2      blue
3      yellow

Contents

packageid      item           size
1              square         A
1              circle         B
1              triangle       C
2              square         A
2              circle         B
3              square         A

如果我们查询{ item:square, size:A },我们只想要{ packages.id:3 }

如果我们查询{ item:square, size:A }{ item:circle, size:B },我们只需要{ packages.id:2 }

如果我们查询{ item:square, size:A }{ item:circle, size:B }{ item:triangle, size:C },我们只需要{ packages.id:1 }

如果有多个完全匹配的包裹,我们希望所有的包裹都匹配.

这似乎很管用,但并不是特别优雅:

SELECT 
p.id,
p.name,
c.item,
c.size

FROM Packages p
LEFT JOIN Contents c ON (
  c.packageid=p.id
)

WHERE (
    ( p.id IN ( SELECT packageid FROM Contents WHERE item='square' AND size='A' ) 
    AND 
    ( p.id IN ( SELECT packageid FROM Contents WHERE item='circle' AND size='B' ) 
)
GROUP BY p.id 
HAVING ( SELECT COUNT(*) FROM Contents WHERE packageid=p.id ) = 2;

推荐答案

有了EXISTS,你就会得到你想要的结果

EXist是判断具有所需值的值是否存在的最快方法.

在poacage_id、项目和大小上建立索引将提高性能

SELECT 
    p.id, p.name, c.item, c.size
FROM
    Packages p
        LEFT JOIN
    Contents c ON (c.packageid = p.id)
WHERE

(SELECT 
        1
   FROM
        Contents
    WHERE
        packageid = p.id AND (item = 'square' AND size = 'A'))
AND (SELECT 
        1
   FROM
        Contents
    WHERE
        packageid = p.id AND (item = 'circle' AND size = 'B')) 
  AND  (SELECT 
        1
   FROM
        Contents
    WHERE
        packageid = p.id AND (item = 'triangle' AND size = 'C')) 
  AND (SELECT COUNT(*) FROM Contents WHERE packageid = p.id) = 3;

id name item size
1 red triangle C
1 red circle B
1 red square A
SELECT
p.id, p.name, c.item, c.size
FROM
    Packages p
        LEFT JOIN
    Contents c ON (c.packageid = p.id)
WHERE

(SELECT 
        1
   FROM
        Contents
    WHERE
        packageid = p.id AND (item = 'square' AND size = 'A'))
AND (SELECT 
        1
   FROM
        Contents
    WHERE
        packageid = p.id AND (item = 'circle' AND size = 'B')) 
  AND (SELECT COUNT(*) FROM Contents WHERE packageid = p.id) = 2;

id name item size
2 blue circle B
2 blue square A

fiddle

Mysql相关问答推荐

SQL Store Procedure Throwing [42000][1064]您在EXECUTE stat USING声明上的SQL语法中有错误

try 使用TypeORM创建新表时出现SQL语法错误

MySQL全文索引和不区分大小写搜索带来的挑战

使用字符串文字与使用日期文字时的SQL行为

如果存在N个特殊行,如何 Select 它们,其余的必须填充常规行,总行数不能超过MySQL中的X行?

如何更新一个巨大的表的 50k 行?

创建 mySQL BEFORE/AFTER UPDATE 触发器

MySQL,递归 CTE.它如何以这种句法形式工作?

如何使用减号运算符编写 sql 查询以返回缺少相应值的行?

基于 3 个条件 Select 3 行的最佳 MySQL 索引和查询

mysql从另一个表中 Select 不相等的值

MySQL使用多列 Select 重复记录

是否可以在 macOS 上只安装 mysqldump

在连接条件上使用 IS NULL 或 IS NOT NULL - 理论问题

如何用一系列日期填充表格?

如何将时刻 JS 时间插入 MySQL

在 MySQL 中删除数据库返回删除数据库错误:66

MySQL术语约束与外键的区别?

我可以在 PHP 中使用 PDO 创建数据库吗?

与 MySql 的连接正在自动中止.如何正确配置Connector/J?