MySQL过滤多对多

时间:2015-10-05 12:30:31

标签: php mysql sql

我有以下表格的多对多:

1)收据

-id
-name

2)成分

-id
-name

3)收据 - 成分

-recept_id
-ingredient_id

现在我想找到有成分列表的收据。例如,所有收据都含有西红柿的成分。 AND' pesto'。 (而不是那些只有番茄'或#39; pesto'。查询将如何显示的收据?

4 个答案:

答案 0 :(得分:1)

试试这个

SELECT r.id, r.name, GROUP_CONCAT(DISTINCT(i.name)) as items
 FROM receipts r
 LEFT JOIN receipts-ingredients ri ON(ri.receipt_id = r.id)
 LEFT JOIN ingredients i ON(ri.ingredient_id = i.id)
 GROUP BY r.id
 HAVING FIND_IN_SET('tomato',items) AND FIND_IN_SET('pesto',items)

答案 1 :(得分:1)

在荷兰板上找到了另一个有效的答案:

SELECT
    r.id,
    r.name
FROM
    receipts r
JOIN
    receipts_ingredients ri
    ON r.id = ri.receipt_id
JOIN
    ingredients i
    ON ri.ingredient_id = i.id
WHERE i.name IN ('tomato', 'pesto')
GROUP BY r.id
HAVING COUNT(*) = 2

答案 2 :(得分:0)

SELECT * FROM 
(SELECT * FROM ingredients AS i 
LEFT JOIN `receipts-ingredients` AS ri ON i.id=ri.ingredient_id 
LEFT JOIN receipts AS r ON ri.recept_id=r.id 
WHERE i.name='tomato') AS Tomato, JOIN 
(SELECT * FROM ingredients AS i 
LEFT JOIN `receipts-ingredients` AS ri ON i.id=ri.ingredient_id 
LEFT JOIN receipts AS r ON ri.recept_id=r.id 
WHERE i.name='pesto') AS Pesto ON Tomato.recept_id=Pesto.recept_id

答案 3 :(得分:0)

这是一种硬编码方法(有更好的答案),但你也可以将它用于特定数据(仅供参考:我添加了字符' i' at the column' recept_id' of '收据 - 成分'表)。

修改

此外,您可能需要在收据 - 成分表名称周围添加反引号。也许将它重命名为receipts_ingredients是个好主意。

SELECT aa.id, aa.name AS receipts_name
FROM receipts AS aa
INNER JOIN `receipts-ingredients` AS bb
ON aa.id = bb.receipt_id
INNER JOIN ingredients AS cc
ON cc.id = bb.ingredient_id
INNER JOIN (
    SELECT aa.id
    FROM receipts AS aa
    INNER JOIN `receipts-ingredients` AS bb
    ON aa.id = bb.receipt_id
    INNER JOIN ingredients AS cc
    ON cc.id = bb.ingredient_id
    WHERE cc.name = 'pesto' 
) _aa
ON aa.id = _aa.id
WHERE cc.name = 'tomato'