以1行和不同列显示结果

Cra*_*lus 1 mysql sql select

假设一个简单的情况下,例如桌子上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连接结果所以它不是我想要的

Tar*_*ryn 8

这可以通过使用带有聚合函数的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)


ype*_*eᵀᴹ 7

除了在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)