如何根据其他列值条件显示列的计数

时间:2016-11-18 03:03:39

标签: sql oracle

我的表格中有以下表格数据

SQL> select * from mate2;  

     A_CD       S_ID       E_CD S_E   S_NE  E_IND  
---------- ---------- ---------- ----- ----- -  
       200          1          2 A     J     Y  
       200          2          3 B     A     N  
       200          3          1 C     D  
       200          4          2 A     C     Y  
       200          5          1 D     C  
       200          6          3 B     N     Y  
       200          7          3 N     K  

我需要通过a_cd和(S_E,S_NE)将不同的s_id组计为具有以下条件的字母代码

1)当E_CD = 2或(E_CD = 3 AND E_IND = N)时取S_NE

2)当E_CD = 1或(E_CD = 3 AND E_IND = Y)时取S_E

3)当E_CD = 3且E_IND为空时,同时取S_E和S_NE

输出应该像

200 A 3
200 B 2
200 c 2
..
...
我写过这样的东西,但它不起作用

select a.a_cd, a.letter_code, COUNT (DISTINCT a.s_id) AS cnt  
           FROM (SELECT m.a_cd,  
                        m.s_id,  
                        CASE  
                           WHEN    (m.e_cd = 1)  
                                OR (m.e_cd = 3 AND m.e_ind = 'Y')  
                           THEN  
                              m.S_E  
                           WHEN (m.e_cd = 2) OR (m.e_cd = 3 AND m.e_ind = 'N') then  m.S_NE  
                           WHEN m.e_ind is null then m.S_NE                      
                        END  
                           AS letter_code from mate2 m  
                   union  
                   SELECT m.a_cd,  
                        m.s_id,  
                        CASE  
                           WHEN    (m.e_cd = 1)  
                                OR (m.e_cd = 3 AND m.e_ind = 'Y')  
                           THEN  
                              m.S_E  
                           WHEN (m.e_cd = 2) OR (m.e_cd = 3 AND m.e_ind = 'N') then  m.S_NE  
                           WHEN m.e_ind is null then m.S_NE                      
                        END  
                           AS letter_code from mate2 m) a group by a.ai_cd,a.letter_code  

1 个答案:

答案 0 :(得分:0)

我对你的批评标准感到有些困惑。您的示例输出也不符合您的选择标准。

但是,您可以在下面找到一个根据您的规则选择正确的中间结果集的查询。只需根据它进行正确的灌浆。

with
mate2(  a_cd, s_id, e_cd, s_e, s_ne, e_ind) as (  
  select 200,    1,    2, 'A',  'J', 'Y'  from dual union all
  select 200,    2,    3, 'B',  'A', 'N'  from dual union all
  select 200,    3,    1, 'C',  'D', null from dual union all
  select 200,    4,    2, 'A',  'C', 'Y'  from dual union all
  select 200,    5,    1, 'D',  'C', null from dual union all
  select 200,    6,    3, 'B',  'N', 'Y'  from dual union all
  select 200,    7,    3, 'N',  'K', null from dual
),
rule_1(rule, a_cd, s_id, letter_code) as (
  -- take the S_NE when E_CD = 2 or (E_CD = 3 AND E_IND = N)
  select 1, a_cd, s_id, s_ne from mate2 where e_cd = 2 or (e_cd = 3 and e_ind = 'N')
),
rule_2(rule, a_cd, s_id, letter_code) as (
  -- take the S_E when E_CD = 1 or (E_CD = 3 AND E_IND = Y)
  select 2, a_cd, s_id, s_e from mate2 where e_cd = 1 or (e_cd = 3 and e_ind = 'Y')
),
rule_3(rule, a_cd, s_id, letter_code) as (
  -- take BOTH the S_E and S_NE when E_CD = 3 and E_IND is null
  select 3, a_cd, s_id, letter_code from mate2 
  unpivot (letter_code for x in (s_ne as '1', s_e as '2'))
  where e_cd = 3 and e_ind is null 
)
-- group the way you like
--select letter_code, count(*) from (
  select * from rule_1
  union all
  select * from rule_2
  union all
  select * from rule_3
--) group by letter_code
--order by 1
;