简体   繁体   中英

mySQL returns wrong Count result

Here is sqlFiddle for my database and my count query...

http://sqlfiddle.com/#!2/45150/6

If I run a select * query, it returns me one row, however when I run count on the same query, it gives me 2 results...

This is the the query for count, it produces different result for "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`

That happens because you're grouping by the user id.

If you want to run a select * then you will have to remove the group by clause. That would return the 2 results that the count(*) is returning. Those results happen to have the same id so they are grouped into only one result.

Edit after radical question change:

In a comment the OP mentioned:

I want to look for any user with more than one categories (coming from search)

That means you can't just blindly join on the categories table. You have to first check whether the user has more than one category assigned (that matches cat_id IN (1, 3, 4) ). You can do that this way:

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%'  
)

Fiddle here .

As you mentioned you can have multiple categories associated with a user. Therefore, using COUNT(*) is not possible in your situation. To fix it you can use either of the following options:

Quite simply, use SELECT COUNT(DISTINCT users . id ), like in this 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`

However, this will only hide the problem. The problem will reappear if you start adding new aggregate functions to your select statement (like SUM(salary), etc.)

The proper solution will be, I guess is to fix the duplication and modify your FROM clause, like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM