计算每个组的字段的出现次数?

时间:2012-05-18 12:09:50

标签: mysql sql

我正在做一个非常复杂的查询,而且我正在最后一步滑倒。

我设法做到这一点:

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

有了上表吗?

2 个答案:

答案 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

尝试此查询并告诉我它是否有效。