假设一个简单的情况下,例如桌子上bug有一列status,可以是open,fixed等等.
如果我想知道有多少错误是开放的,我只是做:    
select count(*) as open_bugs from bugs where status = 'open';  
如果我想知道有多少错误是打开的,我只需:
select count(*) as closed_bugs from bugs where status = 'closed';  
如果想要知道在查询中有多少打开以及有多少关闭,则返回2列中的结果,即
Open | Closed|  
  60    180   
Run Code Online (Sandbox Code Playgroud)
最好的方法是什么?UNION连接结果所以它不是我想要的
这可以通过使用带有聚合函数的CASE表达式来完成.这会将行转换为列:
select
    sum(case when status = 'open' then 1 else 0 end) open_bugs,
    sum(case when status = 'closed' then 1 else 0 end) closed_bugs
from bugs
Run Code Online (Sandbox Code Playgroud)
这也可以使用您的原始查询编写:
select 
   max(case when status = 'open' then total end) open_bugs,
   max(case when status = 'closed' then total end) closed_bugs
from
(
  select status, count(*) as total from bugs where status = 'open' group by status
  union all
  select status, count(*) as total from bugs where status = 'closed' group by status
) d
Run Code Online (Sandbox Code Playgroud)
        除了在CASE整个表格中聚合的变体之外,还有另一种方式.要使用您拥有的查询并将它们放在另一个查询中SELECT:
SELECT 
  ( SELECT COUNT(*) FROM bugs WHERE status = 'open')   AS open_bugs, 
  ( SELECT COUNT(*) FROM bugs WHERE status = 'closed') AS closed_bugs 
FROM dual      -- this line is optional 
 ; 
Run Code Online (Sandbox Code Playgroud)
它的优点是您可以在单个查询中包装来自不同表或联接的计数.
效率也可能存在差异(更糟或更好).使用表和索引进行测试.
您还可以使用GROUP BY在单独的行中获取所有计数(如UNION您所提到的),然后使用另一个聚合将结果转换为一行:
SELECT 
  MIN(CASE WHEN status = 'open'   THEN cnt END) AS open_bugs, 
  MIN(CASE WHEN status = 'closed' THEN cnt END) AS closed_bugs
FROM 
  ( SELECT status, COUNT(*) AS cnt
    FROM bugs 
    WHERE status IN ('open', 'closed')
    GROUP BY status 
  ) AS g
Run Code Online (Sandbox Code Playgroud)
        |   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           182 次  |  
        
|   最近记录:  |