我有一个关于通过选择选项过滤不同产品的问题。该查询已在此处解决:Filter products by options。
我现在的问题是对分页的计数查询。例如,此查询返回37行,计数为1.
SELECT COUNT(DISTINCT p.id) AS number
FROM products p
LEFT JOIN product_categories pc ON p.id = pc.product_id
LEFT JOIN product_images pi ON p.id = pi.product_id
LEFT JOIN product_options po ON p.id = po.product_id
WHERE p.product_active = 1
AND po.option_id IN(1)
AND p.main_price BETWEEN 5250.00 AND 14000.00
GROUP BY(p.id)
HAVING COUNT(DISTINCT po.option_id) = 1
但如果我删除DISTINCT:
SELECT COUNT(p.id) AS number
FROM products p
LEFT JOIN product_categories pc ON p.id = pc.product_id
LEFT JOIN product_images pi ON p.id = pi.product_id
LEFT JOIN product_options po ON p.id = po.product_id
WHERE p.product_active = 1
AND po.option_id IN(1)
AND p.main_price BETWEEN 5250.00 AND 14000.00
GROUP BY(p.id)
HAVING COUNT(DISTINCT po.option_id) = 1
这也返回37行,带有混合数字。
出错了什么?我知道我可以通过在这个结果集上运行附加计数来结果,但我认为这不是正确的解决方案吗?
同样如前一个问题中所建议的那样,有人说我不应该需要DISTINCT,并且由于这个原因,查询被忽略了。你能告诉我这是什么问题吗?
答案 0 :(得分:0)
您的查询的唯一区别在于:
SELECT COUNT(DISTINCT p.id) AS number
VS
SELECT COUNT(p.id) AS number
因此,您获得相同数量的结果行,因为FROM
,WHERE
和HAVING
都是相同的。只有您选择的每行数据不同。
在第一种情况下,它是非空的不同ID的数量,它始终为1,因为您按该ID进行分组。 (你说:查看ID为5的所有记录,并计算你在这些记录中找到多少个不同的ID。好吧,每个ID为5的记录中的ID为5.所以它只有一个ID。)
在第二种情况下,您计算非空的ID。由于ID永远不为null,因此与计算记录相同:COUNT(*)
。而且,您最好使用COUNT(*)
代替模糊COUNT(p.id)
来明确这一点。
答案 1 :(得分:0)
好的家伙现在更清楚了。这样的事情足以解决这个问题吗?
SELECT COUNT(*) AS number
FROM (SELECT p.id
FROM products p
LEFT JOIN product_categories pc ON p.id = pc.product_id
LEFT JOIN product_images pi ON p.id = pi.product_id
LEFT JOIN product_options po ON p.id = po.product_id
WHERE p.product_active = 1
AND po.option_id IN(1)
AND p.main_price BETWEEN 5250.00 AND 14000.00
GROUP BY(p.id)
HAVING COUNT(DISTINCT po.option_id) = 1) AS count_table
我会选择这个。感谢。