有两个表:
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;
型
3条答案
按热度按时间wqlqzqxt1#
使用
EXISTS
,您将获得想要的结果Exist是检查是否存在具有所需值的值的最快方法。
在poacage_id,item和size上的索引将增加性能
字符串
| ID|名称|项目|大小|
| --|--|--|--|
| 1 |红色|三角形|C|
| 1 |红色|圈|B|
| 1 |红色|平方|一|
型
| ID|名称|项目|大小|
| --|--|--|--|
| 2 |蓝色|圈|B|
| 2 |蓝色|平方|一|
fiddle
z6psavjg2#
主要条件是根据给定条件获取与行数精确匹配的程序包。例如,如果传递了两组条件,则应收到程序包2,其中包含两行:
字符串
说明:
这些条件将作为第一个CTE上的数据集传递。
第二个CTE使用窗口函数
COUNT()
对行进行计数。第三个CTE用于合并两个表,并计算每个包的总行数。
最后,为了获得所需的结果,我们必须按项目、大小和计数将筛选器行与组合数据联接起来。
对于这种情况
型
结果如下:
型
Demo here
izj3ouym3#
您可以将
GROUP_CONCAT
与包含所需项目的排序列表的字符串一起使用:字符串
演示:https://dbfiddle.uk/IUBFzsHZ