在多个表中使用count(decode ...)

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在多个表中使用count(decode ...)相关的知识,希望对你有一定的参考价值。

我在以下结构中有三个3个表(具有相同的键):

输入表t1:

file_in| f_in_state|
--------------------   
F01    | 1         |
F02    | 2         |
F21    | 1         |
F41    | 2         |

输入表t2:

line_in| file_in| l_in_state |     
-----------------------------
L001   | F01     | 1         |
L002   | F01     | 2         |
L003   | F01     | 2         |
L004   | F01     | 2         |
L005   | F21     | 1         |
L006   | F21     | 1         |
L007   | F21     | 1         |
L008   | F21     | 1         |

输入表t3:

line_out|line_in| file_in| l_out_state|     
---------------------------------------
D001    |L001    | F01    | 1          |
D002    |L002    | F01    | 1          |
D003    |L003    | F01    | 1          |

我需要计算每个“id in file”中三个表中不同状态的列出现次数,然后将它们组合起来得到如下输出:

file_in_id|file_in_state| A | B | C | D | E |
---------------------------------------------
F01       | 1           | 1 | 3 | 0 | 0 | 3 |
F02       | 2           | 2 | 0 | 0 | 0 | 0 |
F21       | 1           | 1 | 4 | 0 | 0 | 0 |
F41       | 2           | 2 | 0 | 0 | 0 | 0 | 

有:

  • A指的是状态='1'的输入行数(“line_in”)
  • B指的是状态='2'的输入行数(“line_in”)
  • C指的是状态='3'的输入行数(“line_in”)(在我的情况下,没有这种状态的行,但是可能发生)
  • D指的是状态='1'的输出行数(“line_out”)
  • E指的是state ='2'的输出行数(“line_out”)

所以,我试图在我的查询中使用解码函数,但我没有得到希望的结果。

SELECT
    t1.file_in AS file_in_id,    
    t1.f_in_state AS file_in_state,
    COUNT(DECODE(t2.f_in_state, '1', 1, null)) AS A,
    COUNT(DECODE(t2.f_in_state, '2', 1, null)) AS B,
    COUNT(DECODE(t2.f_in_state, '3', 1, null)) AS C,
   COUNT(DECODE(t3.f_out_state, '1', 1, null)) AS D,
   COUNT(DECODE(t3.f_out_state, '2', 1, null)) AS E
FROM table1 t1,
table2 t2,
table3 t3
WHERE t1.file_in = t2.file_in (+)
AND t2.file_in = t3.file_in (+)
GROUP BY t1.file_in, t1.f_in_state
ORDER BY t1.file_in

但是,这就是我得到的:

file_in_id|file_in_state|A |B |C |D |E |
----------------------------------------
F01       |1            |1 |3 |9 |0 |12|
F02       |2            |2 |0 |0 |0 |0 |
F21       |1            |1 |4 |0 |0 |0 |
F41       |2            |2 |0 |0 |0 |0 | 

有人可以告诉我这个查询有什么问题,我该如何修复它以获得我希望得到的结果。

这非常重要,这就是输入表3应该是这样的:

输入表t3:

line_out|*file_out*| file_in| l_out_state|     
---------------------------------------
D001    |W01    | F01    | 1          |
D002    |W01    | F01    | 1          |
D003    |W01    | F01    | 1          |
答案

此查询提供了所需的结果:

select file_in, f_in_state,
       count(case l_in_state  when '1' then 1 end) a,
       count(case l_in_state  when '2' then 1 end) b,
       count(case l_in_state  when '3' then 1 end) c,
       count(case l_out_state when '1' then 1 end) d,
       count(case l_out_state when '2' then 1 end) e
  from t1 
  left join t2 using (file_in)
  left join t3 using (file_in, line_in)
  group by file_in, f_in_state
  order by file_in

如果你有Oracle 11g或更高版本,你也可以使用pivot

测试:

with t1(file_in, f_in_state) as (
    select 'F01', '1' from dual union all
    select 'F02', '2' from dual union all
    select 'F21', '1' from dual union all
    select 'F41', '2' from dual ),
t2(line_in, file_in, l_in_state) as (
    select 'L001', 'F01', '1' from dual union all
    select 'L002', 'F01', '2' from dual union all
    select 'L003', 'F01', '2' from dual union all
    select 'L004', 'F01', '2' from dual union all
    select 'L005', 'F21', '1' from dual union all
    select 'L006', 'F21', '1' from dual union all
    select 'L007', 'F21', '1' from dual union all
    select 'L008', 'F21', '1' from dual ), 
t3(line_out, line_in, file_in, l_out_state) as (
    select 'D001', 'L001', 'F01', '1' from dual union all
    select 'D002', 'L002', 'F01', '1' from dual union all
    select 'D003', 'L003', 'F01', '1' from dual )
select file_in, f_in_state,
       count(case l_in_state  when '1' then 1 end) a,
       count(case l_in_state  when '2' then 1 end) b,
       count(case l_in_state  when '3' then 1 end) c,
       count(case l_out_state when '1' then 1 end) d,
       count(case l_out_state when '2' then 1 end) e
  from t1 
  left join t2 using (file_in)
  left join t3 using (file_in, line_in)
  group by file_in, f_in_state
  order by file_in

输出:

FILE_IN F_IN_STATE          A          B          C          D          E
------- ---------- ---------- ---------- ---------- ---------- ----------
F01     1                   1          3          0          3          0
F02     2                   0          0          0          0          0
F21     1                   4          0          0          0          0
F41     2                   0          0          0          0          0
另一答案

变量与SUM

Select a.file_in, a.f_in_state,
Sum(Case When b.l_in_state=1 Then 1 Else 0 End) A,
Sum(Case When b.l_in_state=2 Then 1 Else 0 End) B,
Sum(Case When b.l_in_state=3 Then 1 Else 0 End) C,
Sum(Case When c.l_out_state=1 Then 1 Else 0 End) D,
Sum(Case When c.l_out_state=2 Then 1 Else 0 End) E
From T1 a
Left join T2 b on a.file_in=b.file_in
Left join T3 c on a.file_in=c.file_in and b.line_in=c.line_in
GROUP BY a.file_in, a.f_in_state
ORDER BY a.file_in

以上是关于在多个表中使用count(decode ...)的主要内容,如果未能解决你的问题,请参考以下文章

当查询返回多个 min(count) 数据时,如何从不同表中选择所有行

Oracle -- 多个count统计一张表中多个字段等于某值

使用Python遇到:'utf-8' codec can't decode byte 0x8b in position 1: invalid start byte 问题(示例代

BigQuery 避免多个子查询

URL地址中中文乱码详解(javascript中encodeURI和decodeURI方法java.net.URLDecoder.encodejava.net.URLDecoder.decode)(代

如何从多个聚合表中检索数据?