3

出于分页原因,我正在对我的数据库运行两个查询。因此,每个查询几乎是相同的。我的 COUNT(*) 查询没有返回非计数查询的结果数。我很困惑为什么会这样。查询如下。

SELECT p.host_id, p.rating_support, p.rating_tech, MAX(p.rating_overall) AS rating_overall, p.publish_rating, h.name, prices.price, prices.term_duration
FROM plans p
INNER JOIN hosts AS h ON h.id = p.host_id
INNER JOIN (SELECT plan_id, price, term_duration FROM prices WHERE price > 0 AND price < 50 AND term_duration = 1) prices ON prices.plan_id = p.id
WHERE p.published = 1 AND h.published = 1
GROUP BY p.host_id
ORDER BY rating_overall desc LIMIT 0, 12

SELECT COUNT(*) AS count
FROM plans p
INNER JOIN hosts AS h ON h.id = p.host_id
INNER JOIN (SELECT plan_id, price, term_duration FROM prices WHERE price > 0 AND price < 50 AND term_duration = 1) prices ON prices.plan_id = p.id
WHERE p.published = 1 AND h.published = 1
GROUP BY p.host_id

我不是 MySQL 专家。除了计数没有提供正确数量的结果外,非计数查询也能完美运行。

对这个问题的任何了解都会很棒。

4

2 回答 2

4

在 Dems 评论的帮助下(在某处寻找并支持他:),我创建了这个查询。请注意,我删除了子查询,因为它似乎没有必要:

SELECT
  COUNT( DISTINCT p.host_id )
FROM       plans p
INNER JOIN hosts h ON h.id = p.host_id
INNER JOIN prices  ON prices.plan_id = p.id
                  AND prices.price > 0
                  AND prices.price < 50
                  AND prices.term_duration = 1
WHERE p.published = 1
  AND h.published = 1

我原来的答案:

要获取总行数,您必须将GROUP BY查询包装到外部SELECT

SELECT COUNT(*)
FROM (
  SELECT NULL -- we are just counting, so we need no actual data -> a bit faster
  FROM       plans p
  INNER JOIN hosts h ON h.id = p.host_id
  INNER JOIN prices  ON prices.plan_id = p.id
                    AND prices.price > 0
                    AND prices.price < 50
                    AND prices.term_duration = 1
  WHERE p.published = 1
    AND h.published = 1
  GROUP BY p.host_id
) AS all_rows_without_data

或者你可以使用SQL_CALC_FOUND_ROWS+FOUND_ROWS()

http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_found-rows

一个 SELECT 语句可能包含一个 LIMIT 子句来限制服务器返回给客户端的行数。在某些情况下,希望知道在没有 LIMIT 的情况下该语句将返回多少行,但无需再次运行该语句。要获取此行数,请在 SELECT 语句中包含 SQL_CALC_FOUND_ROWS 选项,然后调用 FOUND_ROWS():

首先,只需选择所需的行,但添加SQL_CALC_FOUND_ROWS

SELECT SQL_CALC_FOUND_ROWS
  p.host_id, p.rating_support, p.rating_tech,
  MAX(p.rating_overall) AS rating_overall,
  p.publish_rating, h.name, prices.price, prices.term_duration
FROM       plans p
INNER JOIN hosts AS h ON h.id = p.host_id
INNER JOIN prices  ON prices.plan_id = p.id
                  AND prices.price > 0
                  AND prices.price < 50
                  AND prices.term_duration = 1
WHERE p.published = 1 AND h.published = 1
GROUP BY p.host_id
ORDER BY rating_overall desc
LIMIT 0, 12;

其次,如果第一个查询中没有LIMIT语句,则获取将返回的行数:

SELECT FOUND_ROWS();

更新SQL_CALC_FOUND_ROWS+FOUND_ROWS()似乎不太可靠,总是因为未知原因返回零(不仅仅是我:FOUND_ROWS() 一直返回 0):

http://sqlfiddle.com/#!2/7304d/8

于 2012-07-01T08:17:31.850 回答
1

您的第二个查询的结果将返回相同数量的行,但第一行不会给您返回总数。

结果将给出每行每组的计数:

3
5
1
6
etc.
etc.

要将结果放入一行,请在 PHP 中对完整结果集使用COUNT(DISTINCT p.host_id)或。array_sum()

于 2012-07-01T08:35:07.303 回答