【问题标题】:Show "0" in COUNT column when WHERE does not match?当 WHERE 不匹配时,在 COUNT 列中显示“0”?
【发布时间】:2012-03-18 06:08:37
【问题描述】:

我想做的是从一个表中检索所有数据,并按用户在特定类别中玩的游戏数量对它们进行排序。有什么办法可以使用某种“COUNT WHERE”的sql语句吗?

这是我到目前为止所拥有的。如果他们玩过“fps”类别的游戏,它只会返回用户,但我希望它以降序显示所有用户,即使他们没有玩过 fps 游戏。请原谅我蹩脚的桌子

SELECT user_data.user, COUNT(played_games.game_cat) as 'count'
FROM user_data, played_games
WHERE user_data.user_id = played_games.user_id and played_games.game_cat = 'fps'
GROUP BY user_data.user_id
ORDER BY 'count' DESC;

用户数据表

user_id | user

1       | jeff
2       | herb
3       | dug

played_games 表

id | user_id | game | game_cat

1  |    2    | kill | fps
2  |    1    | shoot| fps
3  |    2    | COD  | fps
4  |    3    | dogs | cas

【问题讨论】:

  • 重写为正确的左连接,user_data 在左边,played_games 在右边。这将列出所有用户,并且只为那些实际玩过游戏的人提供非空/非零计数。

标签: php mysql count sql-order-by


【解决方案1】:

您需要LEFT OUTER JOIN 才能获取记录,即使其他表中不存在相应记录。

SELECT user, coalesce(count(game_cat), 0) as count
FROM user_data LEFT OUTER JOIN played_games
ON user_data.user_id = played_games.user_id AND played_games.game_cat='fps'
GROUP BY user_data.user_id 
ORDER BY count desc;

在我的屏幕上显示以下结果

+------+-------+
| user | count |
+------+-------+
| herb |     2 |
| jeff |     1 |
| dug  |     0 |
+------+-------+

【讨论】:

  • 使用 COALESCE 而不是 COUNT(if(game_cat='fps',1,null)) 有什么好处吗?
  • 他最初的查询完全错误。这个更好了,现在他已经编辑了,但是他的 ORDER 子句仍然是错误的(注意他的结果没有排序)
  • @ddan 你尝试了最新的查询吗?
  • 我做了,但它在我的开发计算机上不起作用。虽然它正在使用 sql fiddle。知道为什么它不能在我的开发计算机上运行吗?
【解决方案2】:

我就是这样做的。没有子查询,没有 COALESCE,没有 COUNTIF 垃圾。

SELECT `users`.`user`, COUNT(`played_games`.id) AS `c`
FROM `users`
LEFT OUTER JOIN `played_games` ON
`users`.`user_id` = `played_games`.`user_id`
AND `played_games`.`game_cat` = "fps"
GROUP BY `users`.`user_id`
ORDER BY `c` DESC, `user` ASC

SQLFiddle(不知道你能不能像这样链接它们……)

【讨论】:

  • 从左列拉出所有行,这样即使没有玩过 FPS 的用户也会显示在结果集中。
  • 有什么理由可以在 sql fiddle 上运行,但在我的开发计算机上不行?
  • 结果不正确...按users.user_id排序。
  • 如果您有 GROUP BY 行但没有 ORDER BY 行,就会发生这种情况...请确保您已完全按照显示的方式复制上述查询。
【解决方案3】:

试试这个:

SELECT ud.user, coalesce(sum(pg.game_cat = 'fps'), 0) Total
FROM user_data ud
LEFT JOIN played_games pg ON ud.user_id = pg.user_id
GROUP BY ud.user_id
ORDER BY Total DESC

这将显示所有用户以及他们玩过“fps”类别游戏的次数。

【讨论】:

    【解决方案4】:

    coalesce one 很有希望,但对我不起作用,sigh~我刚刚发现 NULLIF 是解决这个问题的好方法。记得使用左连接

    COUNT( NULLIF(TABLE.ATTR, 1) ) AS total_count
    

    TABLE.ATTR 是一些可以为 NULL 的字段,这里是一个例子:

    SELECT Posts.*, COUNT( NULLIF(Comments.user_email, 1) ) as comment_num 
    FROM (`Posts`)
    LEFT OUTER JOIN `Comments` ON `Comments`.`post_id` = `Posts`.`id` 
    GROUP BY `Posts`.`id`
    LIMIT 5
    

    http://www.bennadel.com/blog/579-SQL-COUNT-NULLIF-Is-Totally-Awesome.htm得到这个想法

    【讨论】:

    • 非常好...抱歉耽搁了
    【解决方案5】:

    下面查询所有游戏类别,用户ID和计数排序

    select * from (SELECT user_data.user, COUNT(played_games.game_cat) as 'count' 
    FROM user_data, played_games 
    WHERE user_data.user_id = played_games.user_id(+) GROUP BY user_data.user_id)
    order by count desc
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-23
      • 2022-06-10
      • 1970-01-01
      • 1970-01-01
      • 2019-09-16
      • 2021-01-30
      • 2020-12-31
      相关资源
      最近更新 更多