我正在做一个非常复杂的查询,而且我正在最后一步滑倒。
我设法做到这一点:
id refid system_id item_description_id system_component_id current_status
711 4fb62cece5313 49 NULL 711 RUNNING
712 4fb62cece547d 49 NULL 712 STOPPED
713 4fb62cece5616 50 NULL 713 RUNNING
714 4fb62cece5803 50 NULL 714 STOPPED
716 4fb62cece5ab8 51 NULL 716 RUNNING
这些是每个系统的每个组件的当前状态。接下来是按系统对它们进行分组并计算“停止”的出现次数。
我的问题是,如果系统从未更新,某些系统将不会有任何带有“STOPPED”的行,或者根本没有任何行。然而,我仍然必须将它们作为结果的一部分。除了这两种情况之外,只需按系统对它们进行分组,即使根本没有停止的组件,结果值也为“1”。
如何进行返回的查询:
system_id status_count
49 1
50 1
51 0
而不是:
system_id status_count
49 1
50 1
51 1
有了上表吗?
答案 0 :(得分:3)
您必须使用SUM(boolean)
,如下所示:
select system_id,
sum(current_status = 'STOPPED') AS stopped_count,
sum(current_status = 'RUNNING') as running_count
from tbl
group by system_id
布尔值在MySQL中自动缩减为整数
输出:
| SYSTEM_ID | STOPPED_COUNT | RUNNING_COUNT |
|-----------|---------------|---------------|
| 49 | 1 | 1 |
| 50 | 1 | 1 |
| 51 | 0 | 1 |
实时测试:http://www.sqlfiddle.com/#!2/d3bcc/2
如果COUNT(或任何聚合函数)来自LEFT JOIN,则必须用COALESCE或ISNULL括起结果:
select system_id,
isnull( sum(current_status = 'STOPPED') , 0 ) AS stopped_count,
isnull( sum(current_status = 'RUNNING') , 0 ) as running_count
from tbl
group by system_id
ANSI SQL兼容:
select system_id,
coalesce( sum(current_status = 'STOPPED') , 0 ) AS stopped_count,
coalesce( sum(current_status = 'RUNNING') , 0 ) as running_count
from tbl
group by system_id
虽然有些数据库有点冗长。 Postgresql:http://www.sqlfiddle.com/#!1/d3bcc/2
select system_id,
sum((current_status = 'STOPPED')::int) AS stopped_count,
sum((current_status = 'RUNNING')::int) as running_count
from tbl
group by system_id
其他数据库:http://www.sqlfiddle.com/#!3/d3bcc/2
select system_id,
count(case when current_status = 'STOPPED' then 1 end) AS stopped_count,
count(case when current_status = 'RUNNING' then 1 end) as running_count
from tbl
group by system_id
答案 1 :(得分:1)
select system_id,
IF( if(currentstaus = 'RUNNING',0.5,0) + if(currentstaus = 'STOPPED',0.5,0)=1,1,0)
AS status_count from table_name group by system_id
尝试此查询并告诉我它是否有效。