Oracle Pivot为什么会产生不存在的结果?

问题描述 投票:1回答:1

我管理着一个数据库,其中保存了从各个站点收集的大量气候数据。这是一个Oracle 12.2 DB,下面是相关表的提要:

FACT =在特定时间进行的单独测量

  • UTC_START =以UTC开始测量的时间
  • LST_START =开始测量的本地标准时间(到特定站点)的时间
  • SERIES_ID =测量值所属系列的ID(FK到SERIES)
  • STATION_ID =进行测量的站点的ID(从FK到STATION)
  • VALUE =测量值

请注意,UTC_START和LST_START始终在每个站点上具有恒定的差异(LST与UTC的偏移量)。我已经确认,在任何情况下UTC_START和LST_START之间的差异都不会超出预期。

SERIES =一系列数据的描述性数据

  • SERIES_ID =系列ID(PK)
  • NAME =系列的文本名称(例如温度)

STATION =站点的描述性数据

  • STATION_ID =工作站的ID(PK)
  • SITE_ID =站点所在站点的ID(大多数站点都有一个站点,但是少数站点有2个站点]
  • SITE_RANK =如果站点超过1个,则站点内站点的等级。
  • EXT_ID =网站的外部ID(提供给我们)

站点的EXT_ID适用于该站点上的所有站点(但除非SITE_RANK == 1,否则不会填充,我知道不是理想的问题,但此处不是问题),并且优先选择排名较低站点的数据。要将这些数据组织成可消耗的格式,我们正在使用PIVOT将在同一站点/同一时间进行的测量收集到行中。

这里是查询:

WITH
    primaries AS (
        SELECT site_id, ext_id
        FROM station
        WHERE site_rank = 1
    ),

    data as (
        SELECT d.site_id, d.utc_start, d.lst_start, s.name, d.value FROM (
            SELECT s.site_id, f.utc_start, f.lst_start, f.series_id, f.value,
                 ROW_NUMBER() over (PARTITION BY s.site_id, f.utc_start, f.series_id ORDER BY s.site_rank) as ORDINAL
                 FROM fact f
                      JOIN station s on f.station_id = s.station_id
        ) d
            JOIN series s ON d.series_id = s.series_id
            WHERE d.ordinal = 1
                AND d.site_id = ?
                AND d.utc_start >= ?
                AND d.utc_start < ?
    )

    records as (

        SELECT * FROM data
        PIVOT (
               MAX(VALUE) AS VALUE
               FOR NAME IN (
                   -- these are a few series that we would want to collect by UTC_START
                   't5' as t5,
                   'p5' as p5,
                   'solrad' as solrad,
                   'str' as str,
                   'stc_05' as stc_05,
                   'rh' as rh,
                   'smv005_05' as smv005_05,
                   'st005_05' as st005_05,
                   'wind' as wind,
                   'wet1' as wet1
                   )
                )
    )

SELECT r.*, p.ext_id
FROM records r JOIN primaries p on r.site_id = p.site_id

在这里事情变得奇怪。该查询在SQLAlchemy,IntelliJ(使用OJDBC Thin)和Orcale SQL Developer中可以完美地工作。但是,当它从我们的Java程序中运行时(相同的JDBC URL和凭据,使用普通的旧JDBC语句和结果集),则给出的结果没有意义。专门针对同一站点,它将返回2行,具有相同的UTC_START,但具有不同的LST_START(回想一下,我已确认这100%不在FACT表中的任何位置发生)。为了确保没有奇怪的参数处理,我们测试了占位符的硬编码值,并在各个客户端之间复制并粘贴了完全相同的查询,唯一返回这些奇怪结果的查询是Java程序(它使用的是与IntelliJ完全相同的OJDBC jar)。

[如果有人有任何见识或可能的原因,将不胜感激。我们现在有点茫然。

java sql oracle jdbc oracle12c
1个回答
0
投票

事实证明Nathan's comment是正确的。尽管似乎违反直觉(至少对我而言),但似乎在DATE列上调用ResultSet.getString实际上将首先转换为Timestamp。除非您另外明确指定,否则时间戳具有使用系统默认时区的默认默认行为。

此默认行为意味着当我们不希望将夏令时考虑在内时,会导致所描述的奇怪行为。

© www.soinside.com 2019 - 2024. All rights reserved.