数据类型为 "date" 的 Oracle sql 查询

Oracle sql query with data type "date"

我对数据类型为“日期”的转换列有疑问。

我有table(我不能改变结构):

id           number(10,0)
time_stamp   date

当我使用 sql 查询时:

  SQL * FROM t; 

我得到了:

 id   time_stamp
    1    01.07.19
    2    20.08.19

但是我需要有时间的日期,所以我使用了:

SELECT  
id
,TO_TIMESTAMP(lr.time_stamp,'DD.MM.YYYY HH24:MI:SS') as dt
FROM t;

我得到了:

  id         dt
  1   01.07.19 00:00:00,000000000
  2   20.08.19 00:00:00,000000000

但是当我使用 TO_CHAR 时,我发现还有时间。

SELECT  
id
,(TO_CHAR(time_stamp, 'DD.MM.YYYY HH24:MI:SS')) as dt
FROM t

我得到了:

  id         dt
  1   01.07.19 17:09:07
  2   20.08.19 21:45:03

我只是需要时间。我尝试在 WHERE 子句中使用它来获得给定范围内的结果。但是当我这样使用它时:

SELECT id
FROM t
WHERE
 TO_TIMESTAMP(TO_CHAR(time_stamp,'DD.MM.YYYY HH24:MI:SS')) >= '01.11.2020 06:00:00' 
 AND TO_TIMESTAMP(TO_CHAR(time_stamp,'DD.MM.YYYY HH24:MI:SS')) <= '02.11.2020 06:00:00'

未完全优化,查询耗时较长。你有什么建议吗? 我总是需要从昨天 06:00 到今天 06:00

的范围

您混淆了存储和表示问题。

日期以自己的内部格式存储,您无法控制。您应该使用日期函数和算术将日期作为日期进行比较。

另一方面,您可以使用字符串格式化方法to_char(),以您喜欢的格式显示它。请注意,在 date 列上应用 to_timestamp() 是 non-sensical,并且可能会产生令人惊讶的结果:它旨在将字符串转换为日期,而不是相反。

假设您想要昨天早上 6 点到今天早上 6 点之间的所有记录,日期显示格式也显示时间部分,那么:

select id, to_char(dt, 'dd.mm.yyyy hh24:mi:ss') dt
from t
where dt >= trunc(sysdate - 1) + 6 / 24
  and dt <  trunc(sysdate) + 6 / 24

您还可以使用区间表达 where 条件:

where dt >= trunc(sysdate - 1) + interval '6' hour
  and dt <  trunc(sysdate) + interval '6' hour

这两个 where 谓词都被称为 SARGable:没有函数应用于被过滤的列,效率更高,并且可以利用现有索引。

在 Oracle 中,Date 数据类型以内部格式存储并且包含精确到秒的日期和时间。您从 table 中选择数据时看到的日期完全取决于当前会话的 NLS 设置。 (NLS_DATE_FORMAT)

因此,您只需按如下方式在查询中使用它:

SELECT ID
  FROM T
 WHERE TIME_STAMP BETWEEN TO_DATE('01.11.2020 06:00:00', 'DD.MM.YYYY HH24:MI:SS') 
                      AND TO_DATE('02.11.2020 06:00:00''DD.MM.YYYY HH24:MI:SS')