WHERE子句子查询不返回所有行

时间:2017-06-14 19:41:39

标签: sql oracle subquery where-clause

当我运行此查询时

select SFRSTCA_CRN       CRN,
   SFRSTCA_BILL_HR   Cr_Hr,
   SFRSTCA_Seq_Number Seq_no       
  from chelink.tmp_stca_201470 
  where SFRSTCA_PIDM = 9573001 
    and SFRSTCA_RSTS_DAte <= '15-oct-14'

我得到以下结果

CRN        CR_HR     SEQ_NO
----- ---------- ----------
74705          1         30 
74705          1         37 
74707          1          9 
74707          1         15 
75093          3          4 
75093          3         14 
75093          3         21 
75627          3          5 
75627          3         13 
75627          3         22 
75627          0         33 
77320          3          6 
77320          3         12 
77320          3         23 
77320          3         35 
77776          3         10 
77776          3         11 
78615          3         31 
78615          3         36 

当我尝试使用where子句中的子查询找到每个CRN的最大Seq_No时,使用此查询

SELECT CRN,
       Cr_Hr,
       Seq_No       
FROM
(select SFRSTCA_CRN       CRN,
        SFRSTCA_PIDM      PIDM,
        SFRSTCA_BILL_HR   Cr_Hr,
        SFRSTCA_Seq_Number Seq_no       
  from chelink.tmp_stca_201470  
  where SFRSTCA_PIDM = 9573001  
   and SFRSTCA_RSTS_DAte <= '15-oct-14'
) STCA_List
WHERE Seq_No = 
      (SELECT Max(SFRSTCA_Seq_Number)
         FROM chelink.tmp_stca_201470 STCA2
        WHERE STCA2.SFRSTCA_PIDM = STCA_List.PIDM
          AND STCA2.SFRSTCA_CRN  = STCA_List.CRN
      )

这些是结果。其中一个CRN失踪(75093)。是什么给了什么?

CRN        CR_HR     SEQ_NO
----- ---------- ----------
74705          1         37 
74707          1         15 
75627          0         33 
77320          3         35 
77776          3         11 
78615          3         36 

1 个答案:

答案 0 :(得分:0)

如果表格中只包含您显示的值:

create table tmp_stca_201470 (sfrstca_crn number, sfrstca_bill_hr number,
  sfrstca_seq_number number , sfrstca_pidm number, sfrstca_rsts_date date);

insert into tmp_stca_201470 (sfrstca_crn, sfrstca_bill_hr,
  sfrstca_seq_number, sfrstca_pidm, sfrstca_rsts_date)
select 74705, 1, 30, 9573001, date '2014-10-15' from dual
union all select 74705, 1, 37, 9573001, date '2014-10-15' from dual
union all select 74707, 1, 9, 9573001, date '2014-10-15' from dual
union all select 74707, 1, 15, 9573001, date '2014-10-15' from dual
union all select 75093, 3, 4, 9573001, date '2014-10-15' from dual
union all select 75093, 3, 14, 9573001, date '2014-10-15' from dual
union all select 75093, 3, 21, 9573001, date '2014-10-15' from dual
union all select 75627, 3, 5, 9573001, date '2014-10-15' from dual
union all select 75627, 3, 13, 9573001, date '2014-10-15' from dual
union all select 75627, 3, 22, 9573001, date '2014-10-15' from dual
union all select 75627, 0, 33, 9573001, date '2014-10-15' from dual
union all select 77320, 3, 6, 9573001, date '2014-10-15' from dual
union all select 77320, 3, 12, 9573001, date '2014-10-15' from dual
union all select 77320, 3, 23, 9573001, date '2014-10-15' from dual
union all select 77320, 3, 35, 9573001, date '2014-10-15' from dual
union all select 77776, 3, 10, 9573001, date '2014-10-15' from dual
union all select 77776, 3, 11, 9573001, date '2014-10-15' from dual
union all select 78615, 3, 31, 9573001, date '2014-10-15' from dual
union all select 78615, 3, 36, 9573001, date '2014-10-15' from dual;

然后你会得到你期望的结果:

select sfrstca_crn crn,
  sfrstca_bill_hr cr_hr,
  sfrstca_seq_number seq_no 
from tmp_stca_201470 
where sfrstca_pidm = 9573001 
and sfrstca_rsts_date <= date '2014-10-15';

       CRN      CR_HR     SEQ_NO
---------- ---------- ----------
     74705          1         30
...
... same 19 rows you had

并从您的第二个查询中获取:

select crn, cr_hr, seq_no
from (
  select sfrstca_crn crn,
    sfrstca_pidm pidm,
    sfrstca_bill_hr cr_hr,
    sfrstca_seq_number seq_no
  from tmp_stca_201470  
  where sfrstca_pidm = 9573001  
  and sfrstca_rsts_date <= date '2014-10-15'
) stca_list
where seq_no = (
  select max(sfrstca_seq_number)
  from tmp_stca_201470 stca2
  where stca2.sfrstca_pidm = stca_list.pidm
  and stca2.sfrstca_crn  = stca_list.crn
);

       CRN      CR_HR     SEQ_NO
---------- ---------- ----------
     74705          1         37
     74707          1         15
     75093          3         21
     75627          0         33
     77320          3         35
     77776          3         11
     78615          3         36

7 rows selected. 

如果您的行序列号较高且日期超出您要过滤的范围,则会出现明显的问题:

insert into tmp_stca_201470 (sfrstca_crn, sfrstca_bill_hr,
  sfrstca_seq_number, sfrstca_pidm, sfrstca_rsts_date)
values (75093, 42, 42, 9573001, date '2014-10-16');

第一个查询仍然获得相同的19行,因为新的查询超出了范围。但第二个得到你实际看到的结果:

select crn, cr_hr, seq_no
from (
  select sfrstca_crn crn,
    sfrstca_pidm pidm,
    sfrstca_bill_hr cr_hr,
    sfrstca_seq_number seq_no
  from tmp_stca_201470  
  where sfrstca_pidm = 9573001  
  and sfrstca_rsts_date <= date '2014-10-15'
) stca_list
where seq_no = (
  select max(sfrstca_seq_number)
  from tmp_stca_201470 stca2
  where stca2.sfrstca_pidm = stca_list.pidm
  and stca2.sfrstca_crn  = stca_list.crn
);
       CRN      CR_HR     SEQ_NO
---------- ---------- ----------
     74705          1         37
     74707          1         15
     75627          0         33
     77320          3         35
     77776          3         11
     78615          3         36

6 rows selected. 

如果您自己运行子查询,获取相关值,您会看到:

select sfrstca_crn, max(sfrstca_seq_number)
from tmp_stca_201470
where sfrstca_pidm = 9573001
group by sfrstca_crn;

SFRSTCA_CRN MAX(SFRSTCA_SEQ_NUMBER)
----------- -----------------------
      75627                      33
      77320                      35
      74707                      15
      75093                      42
      78615                      36
      77776                      11
      74705                      37

7 rows selected. 

但是为75093找到的序列是42,它不在第一个查询的19个值的列表中。

您可以修改子查询以限制在相同的日期范围:

select crn, cr_hr, seq_no
from (
  select sfrstca_crn crn,
    sfrstca_pidm pidm,
    sfrstca_bill_hr cr_hr,
    sfrstca_seq_number seq_no
  from tmp_stca_201470  
  where sfrstca_pidm = 9573001  
  and sfrstca_rsts_date <= date '2014-10-15'
) stca_list
where seq_no = (
  select max(sfrstca_seq_number)
  from tmp_stca_201470 stca2
  where stca2.sfrstca_pidm = stca_list.pidm
  and stca2.sfrstca_crn  = stca_list.crn
  and stca2.sfrstca_rsts_date <= date '2014-10-15'
);

       CRN      CR_HR     SEQ_NO
---------- ---------- ----------
     74705          1         37
     74707          1         15
     75093          3         21
     75627          0         33
     77320          3         35
     77776          3         11
     78615          3         36

7 rows selected. 

但是你可以使用更简单的查询获得相同的结果,只使用the last() function一次只能击中表格:

select sfrstca_crn crn,
  max(sfrstca_bill_hr) keep (dense_rank last order by sfrstca_seq_number) cr_hr,
  max(sfrstca_seq_number) seq_no
from tmp_stca_201470  
where sfrstca_pidm = 9573001  
and sfrstca_rsts_date <= date '2014-10-15'
group by sfrstca_crn;

       CRN      CR_HR     SEQ_NO
---------- ---------- ----------
     74705          1         37
     74707          1         15
     75093          3         21
     75627          0         33
     77320          3         35
     77776          3         11
     78615          3         36

7 rows selected.