首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >令人难以置信,Oracle不时为查询返回不同结果

令人难以置信,Oracle不时为查询返回不同结果
EN

Stack Overflow用户
提问于 2018-10-23 08:03:52
回答 2查看 134关注 0票数 0

我有一个Oracle查询,奇怪的是查询结果有时是不同的。

代码语言:javascript
复制
select 
cast(pmm_datetime - 1 / 24 * utc_offset as timestamp) as pmm_datetime_utc,
count(distinct(NODEB_NAME)) as num_of_recs
from pmmcounter_db.WC_B_NODEBFUNCTION_QH t1 
where pmm_datetime >= to_timestamp('201810230525','YYYYMMDDHH24MI')
and cast(pmm_datetime - 1 / 24 * utc_offset as timestamp) = '2018-10-22 19:15:00.000'
group by cast(pmm_datetime - 1 / 24 * utc_offset as timestamp) 

大多数情况下,查询返回的预期结果如下:

代码语言:javascript
复制
PMM_DATETIME_UTC        NUM_OF_RECS
2018-10-22 19:15:00.000 6930

然而,随机地,它返回如下结果。正如您所看到的,相同的日期时间和状态被分成了几行。

代码语言:javascript
复制
PMM_DATETIME_UTC        NUM_OF_RECS
2018-10-22 19:15:00.000 785
2018-10-22 19:15:00.000 1990
2018-10-22 19:15:00.000 162
2018-10-22 19:15:00.000 3993

更奇怪的是,我试着用QH_NUM_OF_RECS的sum放入另一个组,结果是一样的。看起来Oracle不能按PMM_DATETIME_UTC分组?

这里发生了什么事?为什么查询结果可能不同?

EN

回答 2

Stack Overflow用户

发布于 2018-10-23 17:15:00

不要从TIMESTAMP数据类型中减去数字;这是Oracle应用于DATE数据类型的操作,它将隐式地将您的TIMESTAMP转换为DATE并失去精度(然后您必须应用显式转换来将其转换回来)。

相反,可以减去INTERVAL的倍数(或使用NUMTODSINTERVAL( utc_offset, 'HOUR' )生成间隔):

代码语言:javascript
复制
SELECT pmm_datetime - utc_offset * INTERVAL '1' HOUR as pmm_datetime_utc,
       COUNT( DISTINCT NODEB_NAME ) as num_of_recs
FROM   pmmcounter_db.WC_B_NODEBFUNCTION_QH t1 
WHERE  pmm_datetime >= TIMESTAMP '2018-10-23 05:25:00'
AND    pmm_datetime - utc_offset * INTERVAL '1' HOUR = TIMESTAMP '2018-10-22 19:15:00.000'
GROUP BY pmm_datetime - utc_offset * INTERVAL '1' HOUR

您还可以使用时间戳文字TIMESTAMP '2018-10-22 19:15:00.000',而不是依赖于从字符串到TIMESTAMP数据类型的隐式转换。

您还可以使用TIMESTAMP WITH TIME ZONE数据类型通过FROM_TZ函数和AT TIME ZONE 'UTC'管理到协调时的转换。

为什么查询结果会不一样?

TIMESTAMP(6)数据类型可以包含微秒值。如果您只对微秒值感兴趣,则将该值转换为TIMESTAMP(3)以降低精度。

您可以使用:

代码语言:javascript
复制
SELECT TO_CHAR(
         pmm_datetime - utc_offset * INTERVAL '1' HOUR,
         'YYYY-MM-DD HH24:MI:SS.FF6'
       ) as pmm_datetime_utc,
       COUNT( DISTINCT NODEB_NAME ) as num_of_recs
...

看看是不是这样。

票数 2
EN

Stack Overflow用户

发布于 2018-10-23 12:02:27

尝试使用以下代码。它可以解决这个问题。您在可能返回不同值的selectwheregroup by中重复了cast(pmm_datetime - 1 / 24 * utc_offset as timestamp)表达式。在代码中重复这些行的原因是group by

代码语言:javascript
复制
with
    cte
as
(
select 
    cast(pmm_datetime - 1 / 24 * utc_offset as timestamp)   as pmm_datetime_utc,
    NODEB_NAME                                              as num_of_recs
from
    pmmcounter_db.WC_B_NODEBFUNCTION_QH t1 
where
    pmm_datetime >= to_timestamp('201810230525','YYYYMMDDHH24MI')
)
select
    pmm_datetime_utc,
    count(distinct(NODEB_NAME)) as num_of_recs
from
    cte
where
    pmm_datetime_utc = '2018-10-22 19:15:00.000'
group by
    pmm_datetime_utc;
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52939285

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档