2
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 以获得我想要的记录?

4

3 回答 3

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)

你不需要这个的第一点。

于 2012-06-15T11:23:52.550 回答
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

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

于 2012-06-14T21:33:29.830 回答
1

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

于 2012-06-14T21:30:30.397 回答