如何查找与第二个表有多个关系的记录

时间:2012-06-14 21:23:11

标签: mysql database

table products
--------------
id | title
1  | Product 1
2  | Product 2
3  | Product 3

table categories
----------------
id | title
1  | Cat 1
2  | Cat 2
3  | Cat 3

table products_categories_mm
----------------
id_local | id_foriegn
1        | 2
1        | 3
2        | 3
3        | 2

SELECT * 
FROM products 
    JOIN products_categories_mm ON products.uid=products_categories_mm.uid_local 
    JOIN categories ON products_categories_mm.uid_foreign = categories.uid 
WHERE products.lang_uid IN (0) 
    AND products.page >= 1 
    AND products.page IN (8,9,10,11) 
    AND categories.uid IN (2,3) 
ORDER BY products.datetime DESC

以上查找与类别2和3相关的所有产品。它返回产品记录1,2和3.这很好并且可以按照我的意愿运行。但现在我需要调整查询,以便返回与类别2和类别3相关的产品。

在这种情况下,查询应返回产品1(因为它是与这两个类别相关的唯一产品)。

我尝试将SQL更改为:

SELECT * 
FROM products 
    JOIN products_categories_mm ON products.uid=products_categories_mm.uid_local 
    JOIN categories ON products_categories_mm.uid_foreign = categories.uid 
WHERE products.lang_uid IN (0) 
    AND products.page >= 1 
    AND products.page IN (8,9,10,11) 
    AND (categories.uid = 2 AND categories.uid = 3)
ORDER BY products.datetime DESC

但这没有任何回报。 EXPLAIN说有一个不可能的where子句。

如何更改SQL以获取我想要的记录?

3 个答案:

答案 0 :(得分:1)

SQL的解释是因为2和3的UID将出现在不同的行中,因此不可能有一行UID为2和3的行。最好采用不同的方法。 ..例如说一个子查询。

答案 1 :(得分:1)

SELECT
    a.*
FROM
    products a
INNER JOIN
    products_categories_mm b ON a.uid = b.uid_local
WHERE
    a.lang_uid = 0
    AND a.page IN (8,9,10,11)
    AND b.uid_foreign IN (2,3)
GROUP BY
    a.uid
HAVING
    COUNT(*) = 2
ORDER BY
    a.datetime DESC

2中的COUNT(*) = 2表示您要检查的类别数。如果您希望产品仅在满足3或4个类别时显示,请相应更改该数字。

答案 2 :(得分:1)

这是抱怨,因为你在这一行中有一个简单的逻辑失败:

AND (categories.uid = 2 AND categories.uid = 3)

它永远不会是两个值,只有一个或另一个。你必须意味着:

AND (categories.uid = 2 OR categories.uid = 3)

也可以改写为:

AND (categories.uid IN (2,3))

顺便说一句,有什么意义:

AND products.page >= 1

如果你要进一步过滤它:

AND products.page IN (8,9,10,11)

您不需要第一位。