1

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

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)

也就是说,它只排除了最后一个错误条件。有人知道为什么吗?

4

2 回答 2

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). 见这里。检查你的包围!

于 2012-11-28T13:05:20.543 回答
1

From your first query, I have copied, but re-formatted for readability. Your issue is that all of your "OR" conditions are at the same level as your final "AND" conditions making them qualify.

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 )

I think what you really want is...

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

So, by wrapping all your OR conditions as one, it changes the statement to

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

Per your comment back, the answer is more as Will described, what your query is being interpreted as is PROCESSED as

   ( com2 test )
OR ( com1 test )
OR ( suje test )
OR ( suj test )
OR (( CSA.1 test ) AND ( 55 test ) AND ( null test ))
于 2012-11-28T13:17:56.597 回答