条件有几个OR

时间:2017-06-30 07:51:09

标签: sql oracle

where cdc_date_debut is null
   or cdc_date_fin   is null
   or (select TO_CHAR(SYSDATE, 'DD/MM/YY') from dual)
          between cdc_date_debut and cdc_date_fin
   or (select TO_CHAR(SYSDATE, 'DD/MM/YY') from dual)
          not between cdc_date_debut and cdc_date_fin 

我的问题是我有两个或者是真的情况:今天是cdc_date_debut和cdc_date_fin之间的日期,今天日期不是在cdc_date_debut

之间

在这种情况下,我希望今天只能在cdc_date_debut和cdc_date_fin之间进行日期。

感谢所有帮助

1 个答案:

答案 0 :(得分:0)

  

在这种情况下,我希望今天只能在cdc_date_debut和cdc_date_fin之间进行日期。

然后删除另一个案例:

where cdc_date_debut is null
   or cdc_date_fin   is null
   or SYSDATE between cdc_date_debut and cdc_date_fin

您的过滤器:

(select TO_CHAR(SYSDATE, 'DD/MM/YY') from dual) between cdc_date_debut and cdc_date_fin

没有意义。首先,您不需要子查询,因此可以立即简化为:

TO_CHAR(SYSDATE, 'DD/MM/YY') between cdc_date_debut and cdc_date_fin

然后考虑您拥有的数据类型

String between Date and Date

因此Oracle将执行以下两项操作之一:

  1. 将日期转换为字符串,您的查询将变为TO_CHAR(SYSDATE, 'DD/MM/YY') between TO_CHAR( cdc_date_debut ) and TO_CHAR( cdc_date_fin )。 Oracle将使用NLS_DATE_FORMAT会话参数作为这些隐式转换的格式模型(这会带来我在第二个选项中考虑的问题),然后BETWEEN将使用字符串比较。 .. '12/01/1970' BETWEEN '01/10/2017' AND '13/01/2000'将使用字符串比较返回true(因为12介于0113之间),即使第一个日期不在后两个和开始之间范围之间是在结束之后......
  2. 将字符串转换回日期,您的查询变为TO_DATE( TO_CHAR(SYSDATE, 'DD/MM/YY') ) between cdc_date_debut and cdc_date_fin,Oracle将再次使用NLS_DATE_FORMAT会话参数作为此隐式转换的格式模型,这只会按预期工作如果它也是'DD/MM/YY' - 如果它是'DD/MM/YYYY'那么你的所有日期都将被重新投射到公元1世纪;如果它是'MM/DD/YY'那么你的日期和月份将被交换(如果它不只是抛出异常);还有其他各种错误的组合。为了使事情更有趣,NLS_DATE_FORMAT是一个会话参数,因此每个用户可以有所不同,用户可以在会话中更改它,以便查询可以为您工作,但不适用于具有不同设置的其他用户。
  3. 结论是 - 不要将日期转换为字符串并在比较中使用它。把它留作日期。