具有多个连接的分页计数查询

时间:2017-10-27 15:10:54

标签: mysql sql pagination

我有一个关于通过选择选项过滤不同产品的问题。该查询已在此处解决: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,并且由于这个原因,查询被忽略了。你能告诉我这是什么问题吗?

2 个答案:

答案 0 :(得分:0)

您的查询的唯一区别在于:

SELECT COUNT(DISTINCT p.id) AS number

VS

SELECT COUNT(p.id) AS number

因此,您获得相同数量的结果行,因为FROMWHEREHAVING都是相同的。只有您选择的每行数据不同。

在第一种情况下,它是非空的不同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

我会选择这个。感谢。