PHP MySQL JOIN查询问题

时间:2012-08-26 12:40:21

标签: php mysql join

这个让我非常困惑,在阅读了众多论坛和“如何”网站之后,我想我更加困惑为什么这不起作用。

我加入了2张桌子。

表1(产品)包含我的所有产品详细信息。

表2(评级)包含每种产品的所有评级,每种产品有3个不同评级实体的3个评级。

我正在研究一组AJAX搜索过滤器,需要以包含所有过滤器的方式编写查询。

过滤器包括价格,评论数量,平均评论星级,评级1,评级2,评级3。

价格,num评论和平均星形来自表1(产品)。

评级1,2和3来自表2(评级)。

我的查询需要这样的东西,但是当我知道(在数据库中验证过)我的记录符合我要查询的标准时,这会返回零结果。

SELECT p.id, p.name 
FROM products p 
JOIN ratings r ON p.id = r.id 
WHERE p.num_reviews BETWEEN '0' AND '1000' 
AND p.price BETWEEN '0' AND '500' 
AND p.avg_rvw_stars BETWEEN '0' AND '5' 
AND (r.ratingSource='1' AND (r.rating BETWEEN '1' AND '4')) 
AND (r.ratingSource='2' AND (r.rating BETWEEN '0' AND '100')) 
AND (r.ratingSource='3' AND (r.rating BETWEEN '0' AND '100')) 
ORDER BY p.name ASC

问题似乎存在于最后三个WHERE语句中。如果我删除3中的任何2个,我会得到结果。但是当我包括所有3个时,当有记录符合条件时,我什么也得不到。

如果我将最后两个AND更改为OR,我也会得到结果,但这不是预期或需要的结果集。

我没有正确地写这个吗?

非常感谢任何帮助/指导!!

3 个答案:

答案 0 :(得分:3)

您的问题是您混淆了ANDOR的含义。

你正在寻找具有的东西,例如

r.ratingSource='1'

稍后他们也应该

r.ratingSource='2'

没有任何对此有效的东西,因为它是一件不可能同时存在的东西。所以你需要考虑AND的作用。

如果你有一些EACH结果必须有的东西,你应该使用AND。如果你有他们可能拥有的一组东西,你可以(thing AND otherthing) OR (thing2 and otherthing2)

这是所有基本逻辑:)

我猜你可能是这个意思:

SELECT p.id, p.name 
FROM products p 
JOIN ratings r ON p.id = r.id 
WHERE p.num_reviews BETWEEN '0' AND '1000' 
AND p.price BETWEEN '0' AND '500' 
AND p.avg_rvw_stars BETWEEN '0' AND '5' 
AND (
        (r.ratingSource='1' AND (r.rating BETWEEN '1' AND '4')) 
     OR (r.ratingSource='2' AND (r.rating BETWEEN '0' AND '100')) 
     OR (r.ratingSource='3' AND (r.rating BETWEEN '0' AND '100'))
) 
ORDER BY p.name ASC

答案 1 :(得分:2)

如果您有3个不同的评级行,则无法使用该逻辑。每行检查WHERE条件一次,因此不能有12等级的行。

最简单的方法是加入三次:

SELECT p.id, p.name 
FROM products p 
  JOIN ratings r1 ON  p.id = r1.id 
                  AND r1.ratingSource = 1
                  AND r1.rating BETWEEN 1 AND 4
  JOIN ratings r2 ON  p.id = r2.id 
                  AND r2.ratingSource = 2
                  AND r2.rating BETWEEN 0 AND 100
  JOIN ratings r3 ON  p.id = r3.id
                  AND r3.ratingSource = 3
                  AND r3.rating BETWEEN 0 AND 100
WHERE p.num_reviews BETWEEN 0 AND 1000 
  AND p.price BETWEEN 0 AND 500 
  AND p.avg_rvw_stars BETWEEN 0 AND 5 
ORDER BY p.name ASC ;

答案 2 :(得分:1)

我认为你需要

AND 
(
     (r.ratingSource='1' AND (r.rating BETWEEN '1' AND '4')) 
      OR (r.ratingSource='2' AND (r.rating BETWEEN '0' AND '100')) 
      OR (r.ratingSource='3' AND (r.rating BETWEEN '0' AND '100')) 
    )