【问题标题】:How to search a specific date from a given month and year in oracle?如何在oracle中搜索给定月份和年份的特定日期?
【发布时间】:2023-03-05 00:21:02
【问题描述】:

我得到了 1 月份的月份和 2020 年的年份。现在我想搜索 2020 年 1 月内的日期。假设那一天是 14/01/2020,所以我正在尝试以下代码

select date 
from table X 
where date between to_date(1||'/'||month||'/'||year,'dd/mm/yyyy') 
               and to_date(31||'/'||month||'/'||year,'dd/mm/yyyy')

但是这个范围是一月份的,如果月份是二月或四月有 30 天呢? 如果这个查询不合适,那么如何达到完美的结果呢?

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    你可以像下面那样做,

    从给定日期查找第一个日期和最后一个日期,

    select trunc(date'2020-02-14','MM') first_day,
           last_day(date'2020-02-14') last_day
      from dual;
    

    编辑:来自其他用户的 cmets 所以最终的查询是这样的,

    select date 
    from table X 
    where date between trunc(date'2020-02-14','MM') and last_day(date'2020-02-14');
    

    注意:如果您将日期和时间一起存储,您可能会喜欢@MT0 提供的答案

    【讨论】:

    • @Mahadi Hasan,不是对其他答案的批评,如果您像在问题中构建查询的方式一样使用,您可以利用日期列上的索引(如果有),而如果您使用任何一种转换为月份和年份的函数,你失去了它,而且你必须在两边都转换为你的输入和表格列。最后的选择永远是你的。
    • 这不会在2020-02-29T00:00:01 和2020-02-29T23:59:59 之间找到任何值。
    • 这不能回答问题。它只是返回两个日期而不是过滤一个表。
    • @MT0,你领先了一步。我的意思是你是对的,我不知道日期是如何存储在 OP 的实际表中的。如果时间很重要,那么您是对的,它不会像您指定的那样考虑,应该像您一样以其他方式完成。通常对于 first_day 和 last_day 我遵循这种方式。感谢您以任何方式提出这一点。
    • @Gordon Linoff,我没有验证我看不到的数据,据我了解 OP 的问题,这一切都是为了从给定日期查找第一天和最后一天,并且 OP 已经有他的查询可以容纳比特的地方。
    【解决方案2】:

    您可以通过to_char 转换日期以提取您要比较的部分。

    select * 
    from dates
    where to_char(the_date, 'mm') = '01'
    and to_char(the_date, 'yyyy') = '2020'
    

    SQL-Fiddle 是 here

    【讨论】:

    • 它只是被赞成,我看不到它被标记为已回答
    • 已标记为答案。谢谢。
    【解决方案3】:

    使用TO_DATE( your_year_value || '-' || you_month_value, 'YYYY-MM' ) 将年月值转换为日期,然后获取上限,您可以使用ADD_MONTHS 函数查找下个月的开始:

    SELECT *
    FROM   table_name
    WHERE  date_time >= TO_DATE( 2020 || '-' || 1, 'YYYY-MM' )
    AND    date_time <  ADD_MONTHS( TO_DATE( 2020 || '-' || 1, 'YYYY-MM' ), 1 )
    

    (注意:如果您在日期列上使用 TRUNC 或 TO_CHAR,那么 Oracle 将不会在该列上使用索引;您需要在您使用的确切表达式上使用单独的基于函数的索引. 相反,通过计算年/月输入的范围而不是转换日期列,Oracle 将使用日期列上的索引。)

    (注 2:您不想在范围 2020-01-01 到 2020-01-31 上进行比较,因为这将忽略从 2020-01-31T00:00:01 到 2020-01-31T23:59:59 的任何值。相反,您需要使用范围从2020-01-01 直到但不包括2020-02-01。)

    所以,对于一些测试数据:

    CREATE TABLE table_name ( date_time DATE );
    
    INSERT INTO table_name( date_time )
    SELECT DATE '2020-01-14' FROM DUAL UNION ALL
    SELECT DATE '2020-01-31' + INTERVAL '1' HOUR FROM DUAL UNION ALL
    SELECT DATE '2020-02-01' FROM DUAL
    

    这个输出:

    | DATE_TIME | | :----------------- | | 2020-01-14T00:00:00 | | 2020-01-31T01:00:00 |

    db小提琴here

    【讨论】:

      【解决方案4】:

      您只想检查月份和年份是否匹配,因此不必担心日期。您可以只检查月份和年份是否匹配,而不是检查一个值是否在 2 个特定日期之间。

      SELECT date
        FROM table
       WHERE TO_CHAR(date,'MM-YYYY') = '01-2020'
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-02-15
        • 2017-01-19
        • 1970-01-01
        • 1970-01-01
        • 2017-06-08
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多