Select CASE WHEN ALIAS with COUNT 不返回零值

Select CASE WHEN ALIAS with COUNT not returning ZERO Values

我正在尝试根据分配给他们的文件计算用户数量,并使用以下 MySQL 查询按这些文件的状态分组:

SELECT
  (CASE WHEN F.status IS null THEN 'records' 
   WHEN F.status = 0 THEN 'prospects' 
   WHEN F.status >= 1 AND F.status < 4 THEN 'open'
   WHEN F.status = 4 THEN 'archived' END) AS FileStatus,
  count(DISTINCT U.id) as users
FROM
  users_table U
  LEFT OUTER JOIN files_table as F on (F.user_id = U.id or F.user_id IS NULL)
WHERE U.team = 1  
GROUP BY FileStatus DESC

我的问题是,如果没有用户拥有具有特定状态的文件,则查询不会 return 那一行:

目前查询 returns 值如下:

+------------+-------+
| FileStatus | users |
+------------+-------+
| prospects  |   5   |
| open       |   10  |
| archived   |   12  |
+------------+-------+

但我希望零值或空值也像这样显示:

+------------+-------+
| FileStatus | users |
+------------+-------+
| records    |   0   |
| prospects  |   5   |
| open       |   10  |
| archived   |   12  |
+------------+-------+

我相信这非常简单,但我们将不胜感激✌️

要获取所有文件状态,您需要 table 具有这些状态。如果不可用,您可以使用子查询内联生成它。

其次,用户团队的条件应该是连接条件的一部分,否则(当你把它放在where子句中时)它会把外连接变成内连接。

在对 "records" 计数进行评论之后,无论如何使用外部联接都不再有意义了。我会为该类别建议 union

SELECT     FileStatus,
           count(DISTINCT U.id) as users
FROM       (SELECT 0 as status, 'prospects' as FileStatus
            UNION ALL SELECT 1, 'open'
            UNION ALL SELECT 2, 'open'
            UNION ALL SELECT 3, 'open'
            UNION ALL SELECT 4, 'archived') as C
INNER JOIN files_table as F 
        on F.status = C.status
INNER JOIN users_table U
        on F.user_id = U.id
       and U.team = 1  
GROUP BY   FileStatus DESC
UNION ALL
SELECT    'records',
          count(*)
FROM      users_table
WHERE     id NOT IN (SELECT user_id FROM files_table)
AND       team = 1

如果你想使用范围,那么 return a low/high 在子查询中结束,并相应地调整连接条件:

SELECT     FileStatus,
           count(DISTINCT U.id) as users
FROM       (SELECT 0 as statusFrom, 0 statusTo, 'prospects' as FileStatus
            UNION ALL SELECT 1, 3, 'open'
            UNION ALL SELECT 4, 4, 'archived') as C
INNER JOIN files_table as F 
        on F.status between C.statusFrom and C.statusTo
INNER JOIN users_table U
        on F.user_id = U.id
       and U.team = 1  
GROUP BY   FileStatus DESC
UNION ALL
SELECT    'records',
          count(*)
FROM      users_table
WHERE     id NOT IN (SELECT user_id FROM files_table)
AND       team = 1