【问题标题】:Database date depending on SYSDATE with a condition数据库日期取决于带有条件的 SYSDATE
【发布时间】:2021-03-20 09:35:17
【问题描述】:

我想根据“今天”日期选择并返回一些行。

类似...

 SELECT * FROM my_table
 WHERE 
 //some conditions AND

 my_DATE BETWEEN trunc (sysdate, 'mm')/*current month*/ AND SYSDATE

但是我想返回:

  1. 如果今天的日期“dd”小于 15,则仅显示过去两个月(不包括本月)的行
  2. 如果今天的日期 >= 15,则返回过去两个月(包括本月)的行

我正在考虑一个案例。类似的东西

WHERE 
 (CASE 
    when trunc (sysdate, 'dd') < 15 THEN 
    TO_CHAR(my_DATE, 'MMYYY') BETWEEN TO_CHAR((add_months(sysdate,-3)) AND TO_CHAR((add_months(sysdate,-1))

当我熟悉这个领域时,任何指针都会受到高度赞赏。谢谢

【问题讨论】:

  • 这段代码有效吗?
  • 不,没有用

标签: sql oracle


【解决方案1】:

我会在 sysdate 上进行所有计算,以帮助优化器用户索引:

where datecol >= add_months(trunc(sysdate, 'MON'),
                            (case when extract(day from sysdate) < 15 then -2 else -1 end)
                           ) and
      datecol < add_months(trunc(sysdate, 'MON'),
                            (case when extract(day from sysdate) < 15 then 0 else 1 end)
                           )

编辑:

根据评论:

where datecol >= add_months(trunc(sysdate, 'MON'), -2) and
      datecol < add_months(trunc(sysdate, 'MON'),
                            (case when extract(day from sysdate) < 15 then 0 else 1 end)
                           )

    

【讨论】:

  • 尝试在上面的@APC fiddle (dbfiddle.uk/…) 上使用此功能,但&gt;15 部分应该返回 JAN,因为它是 前两个月
  • @Sight 。 . .当我在 3 月下旬写这篇文章时,您的问题描述了两个范围:1 月 1 日 - 3 月 1 日和 2 月 1 日 - 4 月 1 日。如果你真的想要 12 月 1 日 - 3 月 1 日和 1 月 1 日 - 4 月 1 日,那么只需使用 -3 和-2` 在第一个 case 表达式中。
  • 谢谢@Gordon...我实际上想要一月至二月(如果日期 = 15)我想我需要的是-2-2在第一个 case 表达式中?
  • @Sight 。 . .我编辑了答案。我想你会想要相同的月数,不管我们是什么时候。但是你想改变月数。
【解决方案2】:

如果这代表样本数据:

SQL> alter session set nls_date_format = 'dd.mm.yyyy';

Session altered.

SQL> select * from test order by id;

        ID DATUM
---------- ----------
         1 20.12.2020
         2 07.01.2021
         3 15.02.2021
         4 25.02.2021
         5 10.03.2021

然后看看下面的代码是否有意义。在现实生活中,整个date '&amp;&amp;par_sysdate' 应该被sysdate 替换;出于测试目的,我使用了一个参数作为sysdate 返回今天的日期。

第一个例子:par_sysdate = 10.03.2021(小于 15 天):

SQL> select t.id, t.datum
  2  from test t
  3  where t.datum >=
  4    trunc(add_months(date '&&par_sysdate',
  5                     -case when to_number(to_char(date '&&par_sysdate', 'dd')) < 15 then 2
  6                           else 1
  7                      end
  8                    ), 'mm')
  9    and t.datum < case when to_number(to_char(date '&&par_sysdate', 'dd')) < 15 then
 10                            trunc(date '&&par_sysdate', 'mm')
 11                       else date '&&par_sysdate'
 12                  end;
Enter value for par_sysdate: 2021-03-10

        ID DATUM
---------- ----------
         2 07.01.2021
         3 15.02.2021
         4 25.02.2021

第二个例子:使用今天的日期 (20.03.2021),其中天数大于 15:

SQL> undefine par_sysdate
SQL> /
Enter value for par_sysdate: 2021-03-20

        ID DATUM
---------- ----------
         3 15.02.2021
         4 25.02.2021
         5 10.03.2021

SQL>

或者,正如我所说,使用sysdate

SQL> select t.id, t.datum
  2  from test t
  3  where t.datum >=
  4    trunc(add_months(sysdate,
  5                     -case when to_number(to_char(sysdate, 'dd')) < 15 then 2
  6                           else 1
  7                      end
  8                    ), 'mm')
  9    and t.datum < case when to_number(to_char(sysdate, 'dd')) < 15 then
 10                            trunc(sysdate, 'mm')
 11                       else sysdate
 12                  end;

        ID DATUM
---------- ----------
         3 15.02.2021
         4 25.02.2021
         5 10.03.2021

SQL>

【讨论】:

    【解决方案3】:

    您的要求并不完全清楚,但我认为您想要这样的东西:

    select t.*
    from       mytable t
    where (to_number(to_char(sysdate, 'dd')) < 15
           and t.dt >= add_months(trunc(sysdate, 'mm'),-3)
           and t.dt  < trunc(sysdate, 'mm')
          )
    or    (to_number(to_char(sysdate, 'dd')) >= 15
           and t.dt >= add_months(trunc(sysdate, 'mm'),-2)
           and t.dt <= last_day(sysdate)
          )
    

    我已将a demo version of this code on db<>fiddle 设置为更改今天 的日期而不是使用sysdate。


    根据今天的日期,前几个月应该是 FULL 而不是前几个月。

    要获得完整的月份,请使用 'mm' 掩码截断日期,该掩码返回月份的第一天。

    【讨论】:

    • 你可以简化它并使用EXTRACT( DAY FROM sysdate )而不是链接TO_NUMBERTO_CHAR
    • 感谢db&lt;&gt;fiddle 上的演示版。 &gt;15 部分并没有带来 JAN 日期。就像你说的那样,我的第一条消息可能不是很清楚,但根据今天的日期,前几个月应该是 FULL 而不是前几个月。
    • 为了将来参考,在您的问题中包含示例数据。少数输入日期和 today 的不同值的预期输出将使您的问题更容易理解。
    猜你喜欢
    • 1970-01-01
    • 2015-10-06
    • 2012-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-29
    相关资源
    最近更新 更多