简体   繁体   English

数据类型为“日期”的 Oracle sql 查询

[英]Oracle sql query with data type "date"

i have a problem with conversion column with data type "Date".我对数据类型为“日期”的转换列有问题。

I have table (I can't change the structure):我有表(我不能改变结构):

id           number(10,0)
time_stamp   date

When i used sql query:当我使用 sql 查询时:

  SQL * FROM t; 

I got:我有:

 id   time_stamp
    1    01.07.19
    2    20.08.19

But i need date with time, so i used:但我需要有时间的日期,所以我使用了:

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

I Got:我有:

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

BUT when I use TO_CHAR, I see that there is time.但是当我使用 TO_CHAR 时,我看到有时间。

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

I Got:我有:

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

And I just need time.而我只是需要时间。 I try to use it in the WHERE clause to get results in the given range.我尝试在 WHERE 子句中使用它来获得给定范围内的结果。 But when I use it like this:但是当我像这样使用它时:

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'

it's not exactly optimized and the query takes a long time.它没有完全优化,查询需要很长时间。 Do you have any advice?你有什么建议吗? I always need a range from yesterday 06:00 to today 06:00我总是需要从昨天 06:00 到今天 06:00 的范围

You are mixing storage and representation matters.您正在混合存储和表示问题。

A date is stored in its own, internal format, that you have no control on.日期以其自己的内部格式存储,您无法控制。 You should compare dates as dates, using date functions and arithmetics.您应该使用日期函数和算术将日期与日期进行比较。

On the other hand, you can display it in the format that you like, using string formatting method to_char() .另一方面,您可以使用字符串格式化方法to_char()以您喜欢的格式显示它。 Note that applying to_timestamp() on a date column is non-sensical, and might produce suprising results: it is meant to turn a string to a date, not the other way around.请注意,在date列上应用to_timestamp()是没有意义的,并且可能会产生令人惊讶的结果:它旨在将字符串转换为日期,而不是相反。

Say you want all records between yesterday 6 AM and today 6 AM, with the date displayed in a format that shows the time portion as well, then:假设您想要昨天早上 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

You can also express the where condition using intervals:您还可以使用间隔来表达where条件:

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

Both these where predicates are said SARGable: no function is applied on the column being filtered, which is much more efficient, and may take advantage of an existing index.这两个where谓词都被称为 SARGable:在被过滤的列上没有应用任何函数,这样效率更高,并且可以利用现有索引。

In Oracle, the Date data type is stored in an internal format and contains date and time till seconds precision.在 Oracle 中, Date数据类型以内部格式存储并包含日期和时间直到秒精度。 What you see in date while selecting data from the table totally depends on the NLS setting of the current session.从表中选择数据时您看到的日期完全取决于当前会话的NLS设置。 ( NLS_DATE_FORMAT ) ( NLS_DATE_FORMAT )

So, You will just need to use it as it is in your query as follows:因此,您只需要在查询中使用它,如下所示:

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')

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM