繁体   English   中英

在Oracle中将字符串时间戳转换为本地时区

[英]Converting string timestamp to local-time zone in Oracle

我正在尝试对使用oracle数据库的全球多个手机号码的数据使用情况进行汇总,以获取准确的结果,我的SQL查询需要将此字符串时间戳记转换为我的本地时区+03 ,例如第一个号码的预期时间7803128475转化为03时区后应该是20190606085959

我目前的查询不正确

select sum(data_usage) where timestamp between '20190601000000' and '20190630235959';

`+-------------+------------+----------------+----------+
| MSISDN      | DATA_USAGE | TIMESTAMP      | TIMEZONE |
+-------------+------------+----------------+----------+
| 7803128475  |   1223.323 | 20190606135959 | +08:00   |
| 78093678473 |   1323.323 | 20190607071259 | +05:00   |
| 79093648472 |   1423.323 | 20190609090659 | -06:00   |
+-------------+------------+----------------+----------+`

您可以使用以下命令将字符串转换为实时时间戳:

to_timestamp(TIMESTAMP, 'YYYYMMDDHH24MISS')

然后,您可以声明所在的时区:

from_tz(to_timestamp(TIMESTAMP, 'YYYYMMDDHH24MISS'), TIMEZONE)

或者,您可以组合两个字符串列,并将它们一起转换:

to_timestamp_tz(TIMESTAMP || TIMEZONE, 'YYYYMMDDHH24MISSTZH:TZM')

(您的列名令人困惑,因此我将其大写以试图更清楚地区分它们...)

无论哪种方式,您都可以使用以下方法将其转换为本地时区:

from_tz(to_timestamp(TIMESTAMP, 'YYYYMMDDHH24MISS'), TIMEZONE) at local

或更清楚地表明它正在使用会话时区:

from_tz(to_timestamp(TIMESTAMP, 'YYYYMMDDHH24MISS'), TIMEZONE) at time zone sessiontimezone

或者,如果您实际上想要数据库时区:

from_tz(to_timestamp(TIMESTAMP, 'YYYYMMDDHH24MISS'), TIMEZONE) at time zone dbtimezone

通过将示例数据作为CTE,您可以:

alter session set time_zone = 'Asia/Baghdad';

-- CTE for sample data
with your_table (MSISDN, DATA_USAGE, TIMESTAMP, TIMEZONE) as (
  select '7803128475',  1223.323, '20190606135959', '+08:00' from dual
  union all
  select '78093678473', 1323.323, '20190607071259', '+05:00' from dual
  union all
  select '79093648472', 1423.323, '20190609090659', '-06:00' from dual
)
-- example query
select MSISDN, DATA_USAGE, TIMESTAMP, TIMEZONE,
  to_timestamp(TIMESTAMP, 'YYYYMMDDHH24MISS') as ts,
  from_tz(to_timestamp(TIMESTAMP, 'YYYYMMDDHH24MISS'), TIMEZONE) as tstz,
  from_tz(to_timestamp(TIMESTAMP, 'YYYYMMDDHH24MISS'), TIMEZONE) at local as local_tstz
from your_table;

MSISDN      DATA_USAGE TIMESTAMP      TIMEZO TS                    TSTZ                         LOCAL_TSTZ                        
----------- ---------- -------------- ------ --------------------- ---------------------------- ----------------------------------
7803128475    1223.323 20190606135959 +08:00 2019-06-06 13:59:59.0 2019-06-06 13:59:59.0 +08:00 2019-06-06 08:59:59.0 ASIA/BAGHDAD
78093678473   1323.323 20190607071259 +05:00 2019-06-07 07:12:59.0 2019-06-07 07:12:59.0 +05:00 2019-06-07 05:12:59.0 ASIA/BAGHDAD
79093648472   1423.323 20190609090659 -06:00 2019-06-09 09:06:59.0 2019-06-09 09:06:59.0 -06:00 2019-06-09 18:06:59.0 ASIA/BAGHDAD

如果只打算在子句过滤器中使用转换后的时间,那么只要您说出要与哪个时区进行比较,就根本不需要将其转换为本地时区。 我会使用>=<而不是between

select sum(DATA_USAGE)
from your_table
where from_tz(to_timestamp(TIMESTAMP, 'YYYYMMDDHH24MISS'), TIMEZONE)
  >= timestamp '2019-06-01 00:00:00 Asia/Baghdad'
and from_tz(to_timestamp(Timestamp, 'YYYYMMDDHH24MISS'), TIMEZONE)
  < timestamp '2019-07-01 00:00:00 Asia/Baghdad'

SUM(DATA_USAGE)
---------------
       3969.969

警告该解决方案仅适用于几个Oracle 11g版本,请参见注释。 仅供参考。

(TO_TIMESTAMP(TIMESTAMP, 'YYYYMMDDHH24MISS') AT TIME ZONE TIMEZONE) AT TIME ZONE sessiontimezone另一个选项(TO_TIMESTAMP(TIMESTAMP, 'YYYYMMDDHH24MISS') AT TIME ZONE TIMEZONE) AT TIME ZONE sessiontimezone

演示版

with yourTable (MSISDN, DATA_USAGE, TIMESTAMP, TIMEZONE) as (
  select '7803128475',  1223.323, '20190606135959', '+08:00' from dual
  union all
  select '78093678473', 1323.323, '20190607071259', '+05:00' from dual
  union all
  select '79093648472', 1423.323, '20190609090659', '-06:00' from dual
)
select (TO_TIMESTAMP(TIMESTAMP, 'YYYYMMDDHH24MISS') AT TIME ZONE TIMEZONE) AT TIME ZONE '+05:00' t2 
from yourTable;


T2
06-JUN-19 10.59.59.000000000 AM +05:00
07-JUN-19 07.12.59.000000000 AM +05:00
09-JUN-19 08.06.59.000000000 PM +05:00

暂无
暂无

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

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