Mysql 在一行和不同列中显示结果
假设一个简单的情况,例如一个表bug,它的列状态可以是打开的、已修复的等等。 如果我想知道有多少漏洞是开放的,我只需要做: 从状态为“打开”的bug中选择count*作为打开的bug 如果我想知道有多少漏洞是开放的,我只需要做: 从状态为“已关闭”的bug中选择count*作为已关闭的bug 如果你想知道在一个返回两列结果的查询中有多少个打开的和多少个关闭的,即Mysql 在一行和不同列中显示结果,mysql,sql,select,Mysql,Sql,Select,假设一个简单的情况,例如一个表bug,它的列状态可以是打开的、已修复的等等。 如果我想知道有多少漏洞是开放的,我只需要做: 从状态为“打开”的bug中选择count*作为打开的bug 如果我想知道有多少漏洞是开放的,我只需要做: 从状态为“已关闭”的bug中选择count*作为已关闭的bug 如果你想知道在一个返回两列结果的查询中有多少个打开的和多少个关闭的,即 Open | Closed| 60 180 最好的方法是什么?UNION连接结果,因此它不是我想要的 selec
Open | Closed|
60 180
最好的方法是什么?UNION连接结果,因此它不是我想要的
select count(case when status = 'open' then 1 end) open_bugs,
count(case when status = 'closed' then 1 end) closed_bugs
from bugs
试试这个
select count(case when status = 'open' then 1 end) open_bugs,
count(case when status = 'closed' then 1 end) closed_bugs
from bugs
这可以通过在聚合函数中使用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
这也可以使用原始查询编写:
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
这可以通过在聚合函数中使用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
这也可以使用原始查询编写:
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
除了在整个表中聚合的CASE变量之外,还有另一种方法。要使用您的查询并将其放入另一个查询中,请选择:
它的优点是可以在单个查询中包装来自不同表或联接的计数
在效率上也可能存在差异,或差或好。使用表和索引进行测试
您还可以使用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
除了在整个表中聚合的CASE变量之外,还有另一种方法。要使用您的查询并将其放入另一个查询中,请选择:
它的优点是可以在单个查询中包装来自不同表或联接的计数
在效率上也可能存在差异,或差或好。使用表和索引进行测试
您还可以使用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
案例基本上会遍历每一行,创建一个1/0的不可见行,在外部选择中,它对它们求和,对吗?因为这是聚合数据,所以它只包括与案例中的状态匹配的行。它只是将where过滤器移到聚合函数中。这并不是说我会用第二个版本升级非标准SQL。。。不过,第一个还是+1。@AndriyM修正了,完全错过了。感谢您指出这一点。案例基本上会遍历每一行,创建一个不可见的1/0行,并在外部选择中将它们相加,对吗?因为这是聚合数据,所以它只包含与案例中状态匹配的行。它只是将where过滤器移到聚合函数中。这并不是说我会用第二个版本升级非标准SQL。。。不过,第一个还是+1。@AndriyM修正了,完全错过了。感谢您指出这一点。case基本上会遍历每一行,创建一个不可见的1/0行,并在外部选择中对它们求和,对吗?是的,这将为匹配的条件返回1,为其他条件返回null。当您进行计数时,它将对具有值的行进行计数。大小写基本上会遍历每一行,创建一个不可见的1/0行,并在外部选择中对它们进行求和,对吗?是,这将为匹配的条件返回1,为其他条件返回null。当您进行计数时,它将对具有值的行进行计数