[英]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.