连接表给出了不正确的COUNT(*)值

时间:2013-08-06 22:59:15

标签: mysql

最长的时间我无法弄清楚为什么返回了错误的COUNT(*)值。在逐步删除部分查询后,我终于意识到连接表是错误值背后的原因。

这是我正在使用的查询:

SELECT `profiles`.`logo` AS logo,
       `companies`.`company_name`,
       `companies`.`url_slug`,
       count(*)
FROM (`companies`)

JOIN `users` ON `users`.`id` = `companies`.`user_id`
JOIN `categories` ON `categories`.`company_id` = `companies`.`id`
JOIN `products` ON `products`.`company_id` = `companies`.`id`
JOIN `profiles` ON `profiles`.`company_id` = `companies`.`id`

WHERE `users`.`last_login` IS NOT NULL
  AND `categories`.`category_id` = '3'
  AND `products`.`active` = 1
  AND `products`.`xmp_1` = 1
  AND `products`.`xmp_2` = 1
  AND `profiles`.`field_a` = 1
GROUP BY `companies`.`id`

在我的SQL程序中运行它会返回28行,但COUNT(*)行返回类似于1400的内容。我不知道从哪里开始。我需要一个返回的列,返回28而不是1400。

SQL小提示样本数​​据:http://sqlfiddle.com/#!2/97d2d/9

2 个答案:

答案 0 :(得分:2)

使用简单的查询无法做到这一点。 Chris Hayes展示了一种使用子查询执行此操作的方法,并且有多种方法可以做到这一点。

原因是聚合函数(如COUNT)仅适用于行所代表的GROUP ...在这种情况下,每行代表具有相同公司ID的结果集。在一个简单的查询中,连续字段无法显示超出其内容的聚合信息。

使用子查询,您可以生成第一个表,然后对其进行聚合。或者,您可以使用以下事实:返回的总行数作为元数据包含在数据中,然后发送回最初提交查询的客户端,从而无需将其包含在数据中。

答案 1 :(得分:1)

以下查询有效:

SELECT *, COUNT(*) FROM (
SELECT `profiles`.`logo` AS logo,
       `companies`.`company_name`,
       `companies`.`url_slug`
FROM (`companies`)

JOIN `users` ON `users`.`id` = `companies`.`user_id`
JOIN `categories` ON `categories`.`company_id` = `companies`.`id`
JOIN `products` ON `products`.`company_id` = `companies`.`id`
JOIN `profiles` ON `profiles`.`company_id` = `companies`.`id`

WHERE `users`.`last_login` IS NOT NULL
  #AND `categories`.`category_id` = '3'
  AND `products`.`active` = 1
  #AND `products`.`xmp_1` = 1
  #AND `products`.`xmp_2` = 1
  AND `profiles`.`field_a` = 1
GROUP BY `companies`.`id`
) AS stuff

我认为您的原始COUNT(*)会以某种方式查看加入前条件或预先分组金额。