对多列进行计数和分组

时间:2014-03-27 13:21:11

标签: oracle

我有两张桌子

SYSTEM
sys_id   version  state
(PK)
-------------------------
100        V12     A
101        V12     B
102        V12     A
103        V13     A
104        V13     C
105        V14     A

ENVNT
envnt_id  sys_id
           (FK)
----------------
1          101
2          102
3          103
4          104
5          105
6          106

需要加入此表才能获得以下结果,

               total
version       sys_ids   state A  state B  state C
----------------------------------------------------
V12              3          2       1        0
V13              2          1       0        1
V14              1          1       0        0

我开始喜欢,

SELECT st.version as version, count(st.version) as total sys_ids
FROM SYSTEM st
,ENVNT env
where env.sys_id = st.sys_id group by st.sys_id;

但我对如何进一步暗示这种逻辑毫无头绪。

3 个答案:

答案 0 :(得分:2)

尝试此查询:

select st.version as version, count(st.version) as total sys_ids,count(a),count(b),count(c) from
(
    SELECT sys_id,version,state,
    MAX(DECODE(state,'A',state)) as a,
    MAX(DECODE(state,'B',state)) as b,
    MAX(DECODE(state,'C',state)) as c
    FROM SYSTEM st
    group by sys_id,version,state
) group by version;  

我没有在查询中包含其他表,因为根据您的数据和所需的输出,没有使用其他表。如果您需要其他表格中的数据,您可以尝试使用您在查询中显示的加入。

答案 1 :(得分:0)

不是很清楚你真的想加入牌桌吗?使用您的样本数据,可以在不加入的情况下使用所需的结果:

SQL> with system(sys_id, version, state) as (
  2  select 100,  'V12',  'A' from dual union all
  3  select 101,  'V12',  'B' from dual union all
  4  select 102,  'V12',  'A' from dual union all
  5  select 103,  'V13',  'A' from dual union all
  6  select 104,  'V13',  'C' from dual union all
  7  select 105,  'V14',  'A' from dual
  8  )
  9  select version, count(*) total,
 10  count(decode(state,'A',1)) stateA,
 11  count(decode(state,'B',1)) stateB,
 12  count(decode(state,'C',1)) stateC
 13  from system
 14  group by system.version
 15  /

VER      TOTAL     STATEA     STATEB     STATEC                                 
--- ---------- ---------- ---------- ----------                                 
V12          3          2          1          0                                 
V13          2          1          0          1                                 
V14          1          1          0          0     

但如果您联合表格,您将获得另一个结果(并非所有来自enevt表中系统表的SYS_ID):

SQL> with system(sys_id, version, state) as (
  2  select 100,  'V12',  'A' from dual union all
  3  select 101,  'V12',  'B' from dual union all
  4  select 102,  'V12',  'A' from dual union all
  5  select 103,  'V13',  'A' from dual union all
  6  select 104,  'V13',  'C' from dual union all
  7  select 105,  'V14',  'A' from dual
  8  ),
  9  event(event_id, sys_id) as (
 10  select 1,          101 from dual union all
 11  select 2,          102 from dual union all
 12  select 3,          103 from dual union all
 13  select 4,          104 from dual union all
 14  select 5,          105 from dual union all
 15  select 6,          106 from dual
 16  )
 17  select version, count(*) total,
 18  count(decode(state,'A',1)) stateA,
 19  count(decode(state,'B',1)) stateB,
 20  count(decode(state,'C',1)) stateC
 21  from system, event
 22  where system.sys_id = event.sys_id
 23  group by system.version
 24  /

VER      TOTAL     STATEA     STATEB     STATEC                                 
--- ---------- ---------- ---------- ----------                                 
V12          2          1          1          0                                 
V13          2          1          0          1                                 
V14          1          1          0          0   

这不是ID中的拼写错误吗?

答案 2 :(得分:0)

您只能使用SYSTEM表和PIVOT子句:

with SYSTEM(sys_id, version, state) as
(
  select 100, 'V12', 'A' from dual
  union all
  select 101, 'V12', 'B' from dual
  union all
  select 102, 'V12', 'A' from dual
  union all
  select 103, 'V13', 'A' from dual
  union all
  select 104, 'V13', 'C' from dual
  union all
  select 105, 'V14', 'A' from dual
)
SELECT version, state_a + state_b + state_c total_sys_ids, state_a, state_b, state_c
FROM
(
  select * from SYSTEM st
)
pivot (count(sys_id) for state in ('A' as state_a, 'B' as state_b, 'C' as state_c));

这给出了预期的结果:

    VERSION TOTAL_SYS_IDS   STATE_A STATE_B STATE_C
1   V12     3           2           1       0
2   V13     2           1           0       1
3   V14     1           1           0       0