mySQL 返回错误的计数结果
Posted
技术标签:
【中文标题】mySQL 返回错误的计数结果【英文标题】:mySQL returns wrong Count result 【发布时间】:2013-11-29 04:25:10 【问题描述】:这是我的数据库和计数查询的 sqlFiddle...
http://sqlfiddle.com/#!2/45150/6
如果我运行 select * 查询,它会返回一行,但是当我对同一个查询运行 count 时,它会给我 2 个结果...
这是对count的查询,它对“select *”产生不同的结果
SELECT count(*)
FROM (`user_info`)
JOIN `users` ON `users`.`id`=`user_info`.`user_id`
LEFT JOIN `profile` ON `users`.`id`=`profile`.`user_id`
JOIN `categories` ON `categories`.`user_id` = `users`.`id`
WHERE `users`.`is_enabled` = 1
AND `categories`.`cat_id` IN (1, 3, 4)
AND (
user_info.first_name LIKE '%bob%'
OR user_info.last_name LIKE '%bob%'
OR profile.title LIKE '%bob%'
OR profile.overview LIKE '%bob%'
)
GROUP BY `users`.`id`
【问题讨论】:
select * 为我返回 2 行:sqlfiddle.com/#!2/45150/22 @cha 因为你没有放group by users.id
【参考方案1】:
正如您所提到的,您可以将多个类别与一个用户关联。因此,在您的情况下无法使用 COUNT(*)。要修复它,您可以使用以下任一选项:
很简单,使用 SELECT COUNT(DISTINCT users
.id
),就像在这个 SQL Fiddle 中一样:
SELECT count(distinct `users`.`id`)
FROM (`user_info`)
JOIN `users` ON `users`.`id`=`user_info`.`user_id`
LEFT JOIN `profile` ON `users`.`id`=`profile`.`user_id`
JOIN `categories` ON `categories`.`user_id` = `users`.`id`
WHERE `users`.`is_enabled` = 1
AND `categories`.`cat_id` IN (1, 3, 4)
AND (
user_info.first_name LIKE '%bob%'
OR user_info.last_name LIKE '%bob%'
OR profile.title LIKE '%bob%'
OR profile.overview LIKE '%bob%'
)
GROUP BY `users`.`id`
但是,这只会隐藏问题。如果您开始向 select 语句中添加新的聚合函数(如 SUM(salary) 等),该问题将再次出现
我想正确的解决方案是修复重复并修改您的 FROM 子句,如下所示:
SELECT count(*)
FROM (`user_info`)
JOIN `users` ON `users`.`id`=`user_info`.`user_id`
LEFT JOIN `profile` ON `users`.`id`=`profile`.`user_id`
WHERE `users`.`is_enabled` = 1
AND (
user_info.first_name LIKE '%bob%'
OR user_info.last_name LIKE '%bob%'
OR profile.title LIKE '%bob%'
OR profile.overview LIKE '%bob%'
)
AND `users`.`id` IN (SELECT `user_id` FROM `categories` WHERE `categories`.`cat_id` IN (1, 3, 4) )
GROUP BY `users`.`id`
SQL Fiddle
【讨论】:
【参考方案2】:这是因为您是按用户 ID 分组的。
如果您想运行select *
,则必须删除group by
子句。这将返回 count(*)
返回的 2 个结果。这些结果恰好具有相同的 id,因此它们仅分组为一个结果。
彻底改变问题后编辑:
OP 在评论中提到:
我想查找具有多个类别(来自搜索)的任何用户
这意味着您不能只是盲目地加入类别表。您必须首先检查用户是否分配了多个类别(与cat_id IN (1, 3, 4)
匹配)。你可以这样做:
SELECT * FROM user_info ui
JOIN `users` u ON u.id = ui.user_id
LEFT JOIN profile p ON u.id = p.user_id
JOIN (
SELECT user_id FROM categories
WHERE cat_id IN (1, 3, 4)
GROUP BY user_id
HAVING COUNT(*) > 1
) c ON c.user_id = u.id
WHERE u.is_enabled = 1 AND (
ui.first_name LIKE '%bob%' OR
ui.last_name LIKE '%bob%' OR
p.title LIKE '%bob%' OR
p.overview LIKE '%bob%'
)
小提琴here.
【讨论】:
但我只想看到一个用户?每个用户在类别表中选择了多个类别...我不想重复它们?例如,可以搜索类别 id 1、2、3 并且用户 1 在表中有 1、2、3,它会显示 3 次用户 1,我只想显示他一次??? 我已经解释了为什么wrong Count result
没有错。如果您需要特定的输出,那么您应该将其添加到问题中。无论如何,如果您只想在一行中显示用户......那么什么类别 id 将包含该行?我可以在您添加的查询中看到用户有 cat_id 4 和 1...您会选择在该行中显示哪一个,为什么?
欣赏.. 但你看,在查询中我有 JOIN categories
ON categories
.user_id
= users
.id
AND categories
.cat_id
IN (1, 3, 4) ........ 并且 cat_id 来自数组... 由于为每个用户分配了多个类别,因此复制了行。我得到了正确的结果,问题出在计数上,我该怎么做才能使它正确?
你说I want to look for any user with more than one categories (coming from search)
。 cat_id in (1, 3, 4)
不会为您提供您正在寻找的结果。如果它只匹配1
它会返回它但你说with more than one categories
所以它不应该
欢迎。但请记住,cha 的答案将返回匹配这三个类别中的任何一个的用户。如果您需要让它们匹配多个,则必须使用HAVING COUNT(*) > 1
以上是关于mySQL 返回错误的计数结果的主要内容,如果未能解决你的问题,请参考以下文章