Oracle SQL - 执行顺序或OR / AND条件

时间:2012-11-28 12:59:07

标签: sql oracle

执行查询时得到错误的结果,但是我得到的错误行取决于执行顺序。说明:如果我首先执行Query,如下所示:

select * 
from PROG_TSUJETO_ATRIB_VIG sujetoatri0_ 
where ((sujetoatri0_.valor like 'COM2' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('01/01/2001 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('01/01/2049 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    or((sujetoatri0_.valor like 'COM1' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('01/01/2001 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('01/01/2049 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    or((sujetoatri0_.valor like 'Suje' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('06/06/2015 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('06/06/2015 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    or((sujetoatri0_.valor like 'Suj' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('28/05/2015 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('03/06/2015 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    or((sujetoatri0_.valor like 'CSA.1' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('19/08/2013 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('20/08/2010 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    and(sujetoatri0_.IDN_PARM_ATRIBUTO=55 )and(sujetoatri0_.FECHA_BAJA_LOGICA is NULL )

我得到的结果是:

IDN_SUJETO_ATRIB_VIG    FEC_INI_VIGENCIA    IDN_SUJETO  FEC_FIN_VIGENCIA    VALOR   IDN_PARM_ATRIBUTO   SIOMAUD_USUARIO_ALTA    
1   2000-10-10 00:00:00 2   2050-10-10 00:00:00 COM2    55  (null)  (null)  (null)  (null)  (null)  (null)
2   2000-10-10 00:00:00 1   2050-10-10 00:00:00 COM1    55  (null)  (null)  (null)  (null)  (null)  (null)
541 2015-06-06 00:00:00 1245    2015-06-10 00:00:00 Suje    57  (null)  (null)  (null)  (null)  (null)  (null)
544 2015-05-28 00:00:00 1246    2015-06-03 00:00:00 Suj 57  (null)  (null)  (null)  (null)  (null)  (null)

我不应该得到第3行和第4行,因为我要求55并且有57行。但是更多,如果我改变OR条件的顺序(第3和第5),如下:

select *
from PROG_TSUJETO_ATRIB_VIG sujetoatri0_ 
where ((sujetoatri0_.valor like 'COM2' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('01/01/2001 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('01/01/2049 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    or((sujetoatri0_.valor like 'COM1' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('01/01/2001 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('01/01/2049 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    or((sujetoatri0_.valor like 'CSA.1' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('19/08/2013 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('20/08/2010 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    or((sujetoatri0_.valor like 'Suje' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('06/06/2015 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('06/06/2015 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    or((sujetoatri0_.valor like 'Suj' )and(sujetoatri0_.FEC_INI_VIGENCIA<=to_date('28/05/2015 00:00:00' , 'dd/MM/yyyy HH24:MI:SS'))and(sujetoatri0_.FEC_FIN_VIGENCIA>=to_date('03/06/2015 00:00:00' , 'dd/MM/yyyy HH24:MI:SS')))
    and(sujetoatri0_.IDN_PARM_ATRIBUTO=55 )and(sujetoatri0_.FECHA_BAJA_LOGICA is NULL )

获取的结果是:

IDN_SUJETO_ATRIB_VIG    FEC_INI_VIGENCIA    IDN_SUJETO  FEC_FIN_VIGENCIA    VALOR   IDN_PARM_ATRIBUTO   SIOMAUD_USUARIO_ALTA    SIOMAUD_FECHA_ALTA  SIOMAUD_USUARIO_ULT_MODIF   SIOMAUD_FECHA_ULT_MODIF SIOMAUD_FECHA_BAJA  FECHA_BAJA_LOGICA
1   2000-10-10 00:00:00 2   2050-10-10 00:00:00 COM2    55  (null)  (null)  (null)  (null)  (null)  (null)
2   2000-10-10 00:00:00 1   2050-10-10 00:00:00 COM1    55  (null)  (null)  (null)  (null)  (null)  (null)
337 2011-06-01 00:00:00 1142    2011-06-30 00:00:00 CSA.1   57  (null)  (null)  (null)  (null)  (null)  (null)
541 2015-06-06 00:00:00 1245    2015-06-10 00:00:00 Suje    57  (null)  (null)  (null)  (null)  (null)  (null)

也就是说,它排除了最后的错误状态。 有人知道为什么吗?

2 个答案:

答案 0 :(得分:2)

AND的优先级高于OR - 所以a AND b OR c AND d实际上(a AND b) OR (c AND d)同样,A OR b OR c AND d实际上是A OR b OR (c AND d)。见here。检查您的包围!

答案 1 :(得分:1)

从您的第一个查询开始,我已复制,但为了便于阅读而重新格式化。您的问题是,您的所有“OR”条件与最终“AND”条件处于同一级别,使其符合条件。

select 
      * 
   from 
      PROG_TSUJETO_ATRIB_VIG sujetoatri0_ 
   where 
         (     ( sujetoatri0_.valor like 'COM2' )
           and ( sujetoatri0_.FEC_INI_VIGENCIA <= to_date('01/01/2001 00:00:00', 'dd/MM/yyyy HH24:MI:SS' ))
           and ( sujetoatri0_.FEC_FIN_VIGENCIA >= to_date('01/01/2049 00:00:00', 'dd/MM/yyyy HH24:MI:SS' ))
         )
      or (     ( sujetoatri0_.valor like 'COM1' )
           and ( sujetoatri0_.FEC_INI_VIGENCIA <= to_date('01/01/2001 00:00:00', 'dd/MM/yyyy HH24:MI:SS'))
           and ( sujetoatri0_.FEC_FIN_VIGENCIA >= to_date('01/01/2049 00:00:00', 'dd/MM/yyyy HH24:MI:SS'))
         )
      or (     (  sujetoatri0_.valor like 'Suje' )
           and ( sujetoatri0_.FEC_INI_VIGENCIA <= to_date('06/06/2015 00:00:00', 'dd/MM/yyyy HH24:MI:SS'))
           and ( sujetoatri0_.FEC_FIN_VIGENCIA >= to_date('06/06/2015 00:00:00', 'dd/MM/yyyy HH24:MI:SS'))
         )
      or (     ( sujetoatri0_.valor like 'Suj' )
           and ( sujetoatri0_.FEC_INI_VIGENCIA <= to_date('28/05/2015 00:00:00', 'dd/MM/yyyy HH24:MI:SS'))
           and ( sujetoatri0_.FEC_FIN_VIGENCIA >= to_date('03/06/2015 00:00:00', 'dd/MM/yyyy HH24:MI:SS'))
         )
      or (     ( sujetoatri0_.valor like 'CSA.1' )
           and ( sujetoatri0_.FEC_INI_VIGENCIA <= to_date('19/08/2013 00:00:00', 'dd/MM/yyyy HH24:MI:SS'))
           and ( sujetoatri0_.FEC_FIN_VIGENCIA >= to_date('20/08/2010 00:00:00', 'dd/MM/yyyy HH24:MI:SS'))
         )
     and ( sujetoatri0_.IDN_PARM_ATRIBUTO=55 )
     and ( sujetoatri0_.FECHA_BAJA_LOGICA is NULL )

我认为你真正想要的是......

where (     ( or condition 1)
         OR ( or condition 2)
         OR ( or condition 3)
         OR ( or condition 4)
      )
      AND ( your 55 condition )
      AND ( your null condition )

因此,通过将所有OR条件包装为一个,它将语句更改为

select where ( any of these or conditions )
         AND ( 55 condition )
         AND ( null condition )

根据你的评论,答案更像Will描述的那样,你的查询被解释为处理为

   ( com2 test )
OR ( com1 test )
OR ( suje test )
OR ( suj test )
OR (( CSA.1 test ) AND ( 55 test ) AND ( null test ))