数据类型为 "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')
我对数据类型为“日期”的转换列有疑问。
我有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')