我管理着一个数据库,其中保存了从各个站点收集的大量气候数据。这是一个Oracle 12.2 DB,下面是相关表的提要:
FACT =在特定时间进行的单独测量
请注意,UTC_START和LST_START始终在每个站点上具有恒定的差异(LST与UTC的偏移量)。我已经确认,在任何情况下UTC_START和LST_START之间的差异都不会超出预期。
SERIES =一系列数据的描述性数据
STATION =站点的描述性数据
站点的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)。
[如果有人有任何见识或可能的原因,将不胜感激。我们现在有点茫然。
事实证明Nathan's comment是正确的。尽管似乎违反直觉(至少对我而言),但似乎在DATE列上调用ResultSet.getString实际上将首先转换为Timestamp。除非您另外明确指定,否则时间戳具有使用系统默认时区的默认默认行为。
此默认行为意味着当我们不希望将夏令时考虑在内时,会导致所描述的奇怪行为。