根据另一个表中相应数据的存在过滤查询中的行

时间:2015-07-31 15:50:37

标签: oracle plsql oracle11g

我有以下两个数据表。

test_a
+--------+-----+----------+
| j_code | amt | batch_nr |
+--------+-----+----------+
| AA_001 | 100 |        1 |           test_b
| AA_001 | 300 |        1 |           +--------+
| BB_001 | 350 |        1 |           | j_code |
| FF_001 |  50 |        1 |           +--------+
| BB_001 | 150 |        2 |           | AA_001 |
| CC_001 |  50 |        2 |           | FF_001 |
+--------+-----+----------+           +--------+

我正在尝试调整以下查询,以便它可以使用以下规则:

select
  A.j_code
  , B.j_code
  , A.batch_nr
from test_a A
  left join test_b B ON A.j_code = B.j_code
  left join (select
              test_a.j_code
             from test_a 
               inner join test_b 
                 on test_a.j_code = test_b.j_code 
             where test_a.batch_nr = 2) code_exists 
               on code_exists.j_code = A.j_code
where A.batch_nr = 1
order by A.j_code;

我正在批量运行查询,对于此批次(1),来自test_a的j_code在test_b中有一个通讯员。因此,只需要显示test_a中的j_code

+----------+----------+----------+
| A.j_code | B.j_code | batch_nr |
+----------+----------+----------+
| AA_001   | AA_001   | 1        |
| FF_001   | FF_001   | 1        |
+----------+----------+----------+

问题是当我尝试调整以下场景的查询时。如果我运行批处理2的查询,如果没有通讯员,那么我仍然需要显示来自test_a的批次。

select
  A.j_code
  , B.j_code
  , A.batch_nr
from test_a A
  left join test_b B ON A.j_code = B.j_code
  left join (select
              test_a.j_code
             from test_a 
               inner join test_b 
                 on test_a.j_code = test_b.j_code 
             where test_a.batch_nr = 2) code_exists 
               on code_exists.j_code = A.j_code
where A.batch_nr = 2
order by A.j_code;

预期产出:

+----------+----------+----------+
| A.j_code | B.j_code | batch_nr |
+----------+----------+----------+
| BB_001   | NULL     | 2        |
| CC_001   | NULL     | 2        |
+----------+----------+----------+

我在CASE EXISTS子句中尝试了WHERE的不同方法,但它没有返回预期的结果。

我觉得这很简单,但我不能把手指放在上面。

感谢任何帮助,这里有SQLFiddle可供使用。

1 个答案:

答案 0 :(得分:0)

我会通过使用分析函数来计算B表中存在多少个j_codes,然后根据给定批号是否存在B行,或者B j_code不为null来进行过滤:

with test_a as (select 'AA_001' j_code, 100 amt, 1 batch_nr from dual union all
                select 'AA_001' j_code, 300 amt, 1 batch_nr from dual union all
                select 'BB_001' j_code, 350 amt, 1 batch_nr from dual union all
                select 'FF_001' j_code, 50 amt, 1 batch_nr from dual union all
                select 'BB_001' j_code, 150 amt, 2 batch_nr from dual union all
                select 'CC_001' j_code, 50 amt, 2 batch_nr from dual),
     test_b as (select 'AA_001' j_code from dual union all
                select 'FF_001' j_code from dual),
     -- end of mimicking your test_a and test_b tables
        res as (select a.j_code a_j_code,
                       b.j_code b_j_code,
                       batch_nr,
                       count(b.j_code) over (partition by batch_nr) cnt_b_j_code
                from   test_a a
                       left outer join test_b b on (a.j_code = b.j_code))
select distinct a_j_code,
                b_j_code,
                batch_nr
from   res
where  cnt_b_j_code = 0
or     b_j_code is not null
order by batch_nr, a_j_code;

A_J_CODE B_J_CODE   BATCH_NR
-------- -------- ----------
AA_001   AA_001            1
FF_001   FF_001            1
BB_001                     2
CC_001                     2

这里是SQLFiddle