【问题标题】:Pagination count query with multiple joins具有多个连接的分页计数查询
【发布时间】:2017-10-30 19:59:47
【问题描述】:

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

【问题讨论】:

  • 你的问题是什么?如果您使用 GROUP BY(p.id) ,它将返回 37 行,因为有 37 个不同的 p.ids 。而所有这些 id 只有一个 option_id 那有什么令人困惑的?

标签: mysql sql pagination


【解决方案1】:

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

SELECT COUNT(DISTINCT p.id) AS number

对比

SELECT COUNT(p.id) AS number

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

在第一种情况下,不为空的不同 ID 的数量始终为 1,因为您按该 ID 分组。 (你说:查看所有 ID 为 5 的记录,数一数你在这些记录中找到了多少个不同的 ID。嗯,ID 为 5 的每条记录中的 ID 都是 5。所以它只有一个 ID。)

在第二种情况下,您计算不为空的 ID。由于 ID 永远不会为空,这与计数记录相同:COUNT(*)。您最好使用COUNT(*) 而非混淆的COUNT(p.id) 来明确这一点。

【讨论】:

    【解决方案2】:

    好的,伙计们,现在更清楚了。这样的事情足以解决这个问题吗?

    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
    

    我会选择这个。谢谢。

    【讨论】:

      猜你喜欢
      • 2023-03-14
      • 2020-04-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-01-05
      • 2012-08-24
      • 2023-03-07
      • 1970-01-01
      相关资源
      最近更新 更多