oracle将时间戳转换为其他时间掩码

时间:2012-06-05 20:00:39

标签: sql oracle

如何将这些数字列(timestamp,event_dt)转换为日期或时间掩码? 我正在尝试这个:

    select to_char(timestamp,'YYYY-MON-DD HH24:MI:SS'), domain_c, to_char(event_date,'YYYY-MON-DD HH24:MI:SS'), total_reads from TOP_READ_EVENTS where timestamp= to_char(sysdate-2,'yyyymmdd') || '0000'
                         *
ERROR at line 1:
ORA-01481: invalid number format model


SQL> desc top_read_events;
 Name                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 YEAR                           NUMBER
 QUARTER                        NUMBER
 MONTH                          NUMBER
 DAY                            NUMBER
 HOUR                           NUMBER
 TIMESTAMP                      NUMBER
 DOMAIN_C                       VARCHAR2(255)
 EVENT_DT                       NUMBER
 TOTAL_READS                        NUMBER




select timestamp, domain_c, event_dt, total_reads from TOP_READ_EVENTS where timestamp= to_char(sysdate-2,'yyyymmdd') || '0000'    

 TIMESTAMP DOMAIN_C              EVENT_DT  TOTAL_READS
---------- ------------------------------  ------------ -------------
2.0111E+11 b.e.att-mail.com         2.0111E+11         14406
2.0111E+11 bounce.emailinfo2.bestbuy.com    2.0111E+11         14156
2.0111E+11 bounce.bluestatedigital.com      2.0111E+11         13701
2.0111E+11 plentyoffish.com         2.0111E+11         13384
2.0111E+11 mail.classmates.com          2.0111E+11         13281
2.0111E+11 comcast.net              2.0111E+11         13241
2.0111E+11 uniquelistsmail.com          2.0111E+11         13135
2.0111E+11 tankgorilla.com          2.0111E+11         12835
2.0111E+11 frigidphoenix.com            2.0111E+11         12657

2 个答案:

答案 0 :(得分:5)

首先,从不将日期或时间戳数据类型存储在除日期或时间戳列之外的任何内容中。它不会导致疼痛;当你正在聚会。

由于你的“时间戳”有11个数量级,我猜你是以yyyymmddhh24mi的形式插入它们,并且它们不是因为一个未指定的纪元或其他任何类似的纪录。

如果你想转换它,那么你必须首先将它们转换为字符,然后转换为日期。您实际上并不需要时间戳,因为这些时间戳仅与小数秒内的日期不同。

看起来如下:

select to_date(to_char(timestamp),'yyyymmddhh24mi') as my_timestamp
  from top_read_events

在旁注上从不调用列时间戳,日期,组或其他保留字。它会导致太多问题。我通常会选择“tstamp”,但这只是个人偏好。

如果您想将“时间戳”转换为字符,则必须再次将其转换为字符。

select to_char(to_date(to_char(timestamp)
                       ,'yyyymmddhh24mi')
              ,'yyyy-mon-dd hh24:mi:ss') as my_timestamp
  from top_read_events

秒数始终为00,因为您没有这些。请注意,我只使用显式编号来表示字符转换的日期。对于那些追随你的人,包括你自己2年后的编码员来说,这更加明显,并且翻译人员没有机会犯错误并将数字与角色等进行比较。

出于这个原因,我肯定会改变where timestamp= to_char(sysdate-2,'yyyymmdd') || '0000'。如你所愿,将比较改为日期和那样,即

where trunc(to_date(to_char(timestamp),'yyyymmddhh24mi'),'dd') = trunc(sysdate -2)

trunc()在此实例中的日期级别截断此内容。

答案 1 :(得分:2)

首先,将日期和时间戳存储在非DATETIMESTAMP的列中是糟糕的数据建模。如果将数据存储在具有适当数据类型的列中,生活会更容易。

其次,您的数字列用于存储日期和/或时间戳数据的格式是什么?你没有发布一个实际值的例子 - 我们所知道的是它们是12位数并从2011年开始。我猜它们是以YYYYMMDDHH24MI格式存储而没有秒 - 你需要告诉它我们,如果那个猜测恰好是错误的。

假设猜测是正确的,您需要将数字转换为字符串,将字符串转换为日期,然后将日期转换回不同格式的另一个字符串。显然,这有点尴尬(以及在适当的数据类型中存储事物的众多原因之一)。像

这样的东西
to_char( to_date( to_char( timestamp ), 
                  'YYYYMMDDHH24MI' ),
         'YYYY-MON-DD HH24:MI:SS' )

如果您的数字列以不同方式存储,或者在任何情况下数据未以正确格式存储,则生活变得更加愉快。