【问题标题】:SQL Oracle table blank when trying to query date data stored as varchar尝试查询存储为 varchar 的日期数据时 SQL Oracle 表空白
【发布时间】:2023-02-08 18:26:03
【问题描述】:

我在 Varchar 中有一个名为 received_dt_key 的列,格式为 DD-MM-YYYY(例如 30-07-2021)。

我想从表格中选择 31-12-2021 和 01-01-2022 之间的所有日期。我已经尝试了以下查询的版本,输出是一个空白表。

SELECT *
FROM SD_BDAY
WHERE to_char(to_date(RECEIVED_DT_KEY, 'DD-MM-YYYY')) > to_char(to_date('31-12-2021', 'DD-MM-YYYY'))
and to_char(to_date(RECEIVED_DT_KEY, 'DD-MM-YYYY')) < to_char(to_date('01-01-2022', 'DD-MM-YYYY'));

【问题讨论】:

  • 正如your previous question 告诉您的那样,将日期与日期进行比较——不要再次将它们转换回字符串。您在会话的 NLS_DATE_FORMAT 中作为字符串进行比较。删除所有 to_char() 调用,看看会发生什么。 (为什么要将日期存储为字符串?这是不好的做法。)
  • 嗨,亚历克斯,抱歉,是的,我试过了,但桌子还是空白的。不幸的是,这是一张非常旧的桌子。
  • 那么,无论您的数据如何,都不会同时存在 > 2021-12-31 和 < 2022-01-01 - 它们是互斥的。

标签: sql oracle date between to-date


【解决方案1】:

不要将日期作为字符串进行比较。将它们作为日期进行比较:

SELECT *
FROM SD_BDAY
WHERE to_date(RECEIVED_DT_KEY, 'DD-MM-YYYY') > to_date('31-12-2021', 'DD-MM-YYYY')
and   to_date(RECEIVED_DT_KEY, 'DD-MM-YYYY') < to_date('01-01-2022', 'DD-MM-YYYY');

如果您尝试将它们作为字符串进行比较,那么您正在寻找大于 '31-12-2021' 且小于 '01-01-2022' 的字符串,并且字符串比较将查看第一个字符并查看它是否可以找到大于 @ 的匹配项987654324@和小于'0';永远不会有这样的匹配,所以当比较字符串时没有返回任何东西是完全正确的。

【讨论】:

    【解决方案2】:

    最好的办法是将日历日期存储在日期数据类型列中。您认为 Oracle 为什么要设计这种数据类型?通过这种方式,您可以在数据数据类型列上创建普通索引,或者,如果需要,可以按该日期列对表进行分区。

    不过,如果您坚持要像这样存储日历日期,我认为以下内容应该有效:

    SELECT *
    FROM SD_BDAY
    WHERE to_date(RECEIVED_DT_KEY, 'DD-MM-YYYY') > 
        to_date('31-12-2021', 'DD-MM-YYYY')
      and to_date(RECEIVED_DT_KEY, 'DD-MM-YYYY') < 
        to_date('01-01-2022', 'DD-MM-YYYY');
    

    因此,您将日历日期与日历日期进行比较,而不是将 varchar 与 varchar 进行比较,因为它是您编写的代码的结果。 如果在 varchar2 列中有一些无法转换为日期的东西怎么办?这就是为什么最好使用日期数据类型的原因。

    【讨论】:

      猜你喜欢
      • 2014-02-13
      • 2021-04-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-08-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多