SQL Oracle Unix时间戳转换

时间:2018-08-21 14:54:09

标签: sql oracle

我有两个查询会给我不同的结果,有人可以解释为什么会这样吗?

第一个查询使用unixtime 1533624035000,它表示“ 07.08.2018 08:40:35”(UTC + 2)

select floor((Buchungsdatum - 1533624035000) / (1000*60*60*24)) as Tag, 
       s.Kurztext as Buchungsstatus,
       count(*) as Anzahl
from PfdBuchung b, Schluesselbegriff s
where b.Buchungsdatum >= 1533624035000 and b.SHKennung = 'H' and
      b.Buchungsstatus=s.Begriff and s.Oberbegriff='Buchungsstatus' and
      b.rzMandant = s.rzMandant
group by floor((Buchungsdatum - 1533624035000) / (1000*60*60*24)),   s.Kurztext 
order by 1,2`

结果

0   verarbeitet 21800
1   verarbeitet 23380
i have just posted the first two results here

在第二个查询中,我使用POSIX_TO_TIMESTAMP函数将unixtimestamp转换为日期时间,该函数将我的unixts简单地转换为

l_ora_timestamp := to_timestamp( '1970-01-01 02:00:00', 'yyyy-mm-dd HH24:MI:SS' ) + numtodsinterval( (ptime/1000), 'SECOND' )

select TO_CHAR(POSIX_TO_TIMESTAMP(b.Buchungsdatum), 'YYYY-MM-DD') as Tag,
       s.Kurztext as Buchungsstatus, count(*) as Anzahl
from PfdBuchung b, Schluesselbegriff s
where TO_CHAR(POSIX_TO_TIMESTAMP(b.Buchungsdatum), 'YYYY-MM-DD') >= '2018-08-07' and
      b.SHKennung = 'H' and
      b.Buchungsstatus = s.Begriff and
      s.Oberbegriff = 'Buchungsstatus' and
      b.rzMandant = s.rzMandant
group by TO_CHAR(POSIX_TO_TIMESTAMP(b.Buchungsdatum), 'YYYY-MM-DD'), s.Kurztext
order by 1,2

结果:

2018-08-07  verarbeitet 15553
2018-08-08  verarbeitet 23315

2 个答案:

答案 0 :(得分:2)

原因很明显。

两个查询都对UNIX时间戳在2018年8月7日世界标准时间06:40:35之后的行进行计数。

第一个查询从这个时间点开始分为24小时的窗口。也就是说,输出的第一行从8月7日的06:40:35到8月8日的同一时间对输入行进行计数,等等。

第二个查询计算从午夜到午夜按日历天(UTC)分组的行。

没有理由匹配计数。

在第二个查询中,您对8月7日的行进行计数,但是仅选择了带有时间戳的06:40:35之后的输入行-这就是为什么您只获得约15,000计数,而所有计数约为20k的原因(满!)24小时窗口。

这与时区无关。您可能自己是UTC + 2的用户,但我看不出您的计算中对时区有何考虑。

答案 1 :(得分:1)

由于夏令时,您的功能POSIX_TO_TIMESTAMP在冬季将是错误的。更好地使用

l_ora_timestamp := (timestamp '1970-01-01 00:00:00 UTC' + numtodsinterval(ptime/1000, 'SECOND')) AT TIME ZONE 'Europe/Berlin';