Sql 令人难以置信的是,Oracle有时会返回不同的查询结果

Sql 令人难以置信的是,Oracle有时会返回不同的查询结果,sql,oracle,Sql,Oracle,我有一个Oracle查询,奇怪的是查询结果有时是不同的 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

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

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) 
大多数情况下,查询返回的预期结果如下:

PMM_DATETIME_UTC        NUM_OF_RECS
2018-10-22 19:15:00.000 6930
但是,它随机返回如下结果。如您所见,相同的日期时间和状态被划分为几行

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
更奇怪的是,我试着用sum来表示QH_NUM_OF_rec的另一个组,结果是一样的。Oracle似乎无法按PMM\u DATETIME\u UTC进行分组


这是怎么回事?为什么查询结果可能不同?????

请尝试使用以下代码。它可以解决这个问题。您重复了
cast(pmm_datetime-1/24*utc_offset作为时间戳)
表达式,在中选择其中的分组依据,这些表达式可能返回不同的值。重复代码中的行的原因是
分组依据

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;

尝试使用以下代码。它可以解决这个问题。您重复了
cast(pmm_datetime-1/24*utc_offset作为时间戳)
表达式,在中选择其中的分组依据,这些表达式可能返回不同的值。重复代码中的行的原因是
分组依据

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;

不要从
时间戳
数据类型中减去数字;Oracle将此操作应用于
日期
数据类型,并将
时间戳
隐式转换为
日期
,从而失去精度(然后必须应用显式转换才能将其转换回)

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

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

您还可以使用带有时区的
时间戳
数据类型,使用
FROM_TZ
功能和
时区“UTC”
管理到UTC的转换

为什么查询结果会不同

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

您可以使用:

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
...

查看是否是这种情况。

不要从
时间戳
数据类型中减去数字;Oracle将此操作应用于
日期
数据类型,并将
时间戳
隐式转换为
日期
,从而失去精度(然后必须应用显式转换才能将其转换回)

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

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

您还可以使用带有时区的
时间戳
数据类型,使用
FROM_TZ
功能和
时区“UTC”
管理到UTC的转换

为什么查询结果会不同

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

您可以使用:

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
...

查看是否是这种情况。

pmm_datetime是日期、时间戳、带时区的时间戳吗?@tbone pmm_datetime是时间戳(6)。例如“2018-10-23 05:00:00.000”请注意,
时间戳(6)
也可以存储
2018-10-22 18:15:00.000111
2018-10-22 18:15:00.000999
@a_horse_,理论上,是的。我们所有的时间戳都四舍五入到15分钟。pmm_datetime是日期、时间戳、带时区的时间戳吗?@tbone pmm_datetime是时间戳(6)。例如“2018-10-23 05:00:00.000”请注意,
时间戳(6)
也可以存储
2018-10-22 18:15:00.000111
2018-10-22 18:15:00.000999
@a_horse_,理论上,是的。我们所有的时间戳都四舍五入到15分钟。为什么这会有什么不同呢
utc_offset
似乎是一个常数(关于查询的单个执行),而
pmm_datetime
是存储在列中的
时间戳(6)
值,在查询的不同部分执行期间两者都不会变化。感谢Mohammad,您建议的查询在ORA-00979中失败。不是表达式分组。:@user3893836你说得对。很抱歉,查询中出现了一些错误。我更新了答案。@MT0
group by
是在该查询结果集中进行更改的唯一子句。我的意思是,
pmm\u datetime\u utc
列有一些不同的值进行了更改。为什么会有任何不同
utc_offset
似乎是一个常数(关于查询的单个执行),而
pmm_datetime
是存储在列中的
时间戳(6)
值,在查询的不同部分执行期间两者都不会变化。感谢Mohammad,您建议的查询在ORA-00979中失败。不是表达式分组。:@user3893836你说得对。很抱歉,查询中出现了一些错误。我更新了答案。@MT0
group by
是在该查询结果集中进行更改的唯一子句。我的意思是,
pmm\u datetime\u utc
列有一些不同的值进行了更改。很好,它解决了问题。中间的转换是不必要的,在这种情况下是有问题的。你认为这是甲骨文方面的问题吗?太好了,它解决了问题。中间的转换是不必要的,在这种情况下是有问题的。你认为这是甲骨文方面的问题吗?