【问题标题】:Use count(decode...) across multiple tables在多个表中使用 count(decode...)
【发布时间】:2017-12-15 10:45:37
【问题描述】:

我有以下结构的三个 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          |

我需要为每个 "file in id" 计算在我的三个表中引用不同状态的列的出现次数,然后将它们组合到得到这样的输出:

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 指状态 = '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          |

【问题讨论】:

  • 您能否使用显式现代联接重写您的问题中的查询? (+) 符号使您更难理解您在做什么。
  • + 使用 decode() 而不是更简单的 SQL 标准案例表达式也是如此......
  • 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 left join table2 t2 on t1.file_in = t2.file_in left join table3 t3 on t2.file_in = t3.file_in GROUP BY t1 .file_in, t1.f_in_state ORDER BY t1.file_in
  • 不要将 cmets 用于代码,您最好针对此类问题编辑您的问题,但现在无论如何都有答案了。您会发现,对于这里的任何问题,您都希望使用 ANSI 标准连接语法。

标签: oracle count decode


【解决方案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

【讨论】:

  • 我认为数据透视对我没有帮助,因为我在运行查询时不知道表格内容。
  • 我在第三张桌子上犯了一个错误,我认为这可能会改变游戏规则。实际上,table3 的第二列应该是 "file_out" 而不是 "LINE_IN"。这样一来,我认为不可能进行下面的连接(left join t3 using (file_in, line_in))很抱歉现在告诉你这个。
【解决方案2】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-12-25
    • 2020-01-20
    • 2018-12-08
    • 1970-01-01
    • 2010-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多