使用隐含/推断数据连接表

Join tables with Implied / Inferred data

这将是一个简单的联接,除了:Table A 对于所有时间和值都是显式的,但是 Table B 仅在与先前值发生变化时才记录行。在查看 Table B 时,可以轻松推断出缺失的时间和值,但如何将其放入查询中?

A.time 中的数据包含每一分钟和相应的 A.Value。

A.Time...........A.Value

9:00...............3.4

9:01...............5.0

9:02...............5.3

9:03...............5.3

9:04...............5.3

and so on…..

Table B 仅包含 B.value 已从先前值更改的行。

B.Time..............B.Value

9:00...................4

9:01...................4.1

This is blank, but I know it to be 9:02 / 4.1

This is blank, but I know it to be 9:03 / 4.1

9:04....................4.7

and so on…

我需要做一个链接 A.Time 和 B.Value 的查询,但我需要查询来理解 Table B 中缺失的时间应该由 B.value 之前的第一个 B.Time。

最终table应该是

A.Time...............B.Value

9:00...................4

9:01...................4.1

9:02...................4.1

9:03...................4.1

9:04...................4.7

我目前正在为 SQL 服务器写这篇文章,但我也需要一个 Oracle 解决方案 提前致谢;

在Oracle中,你可以LEFT JOIN得到所有的时间,然后用LAST_VALUE(b.value) IGNORE NULLS...填空。 (注意:ROWS BETWEEN... 部分与 OVER() 子句中的 ORDER BY 是多余的,但为了更加清晰,我喜欢它。

像这样:

SELECT a.time,
       LAST_VALUE (b.VALUE)
         IGNORE NULLS
         OVER (PARTITION BY NULL 
               ORDER BY a.time 
               ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM   table_a a 
LEFT JOIN table_b b ON b.time = a.time
ORDER BY a.time;

这是一个完整的测试数据示例:

with table_a ( time, value ) as
  ( SELECT '9:00', 3.4 FROM DUAL UNION ALL
    SELECT '9:01', 5.0 FROM DUAL UNION ALL
    SELECT '9:02', 5.3 FROM DUAL UNION ALL
    SELECT '9:03', 5.3 FROM DUAL UNION ALL
    SELECT '9:04', 5.3 FROM DUAL ),
table_b ( time, value ) as 
  ( SELECT '9:00', 4 FROM DUAL UNION ALL
    SELECT '9:01', 4.1 FROM DUAL UNION ALL
    SELECT '9:04', 4.7 FROM DUAL )
SELECT a.time,
       LAST_VALUE (b.VALUE)
         IGNORE NULLS
         OVER (PARTITION BY NULL 
               ORDER BY a.time 
               ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW)
FROM   table_a a 
LEFT JOIN table_b b ON b.time = a.time
ORDER BY a.time;

另一种方法(可能 在 SQL 服务器上工作)是使用 OUTER APPLY。像这样:

SELECT a.time, b.value
FROM   table_a a 
OUTER APPLY ( SELECT * 
              FROM table_b b 
              WHERE b.time <= a.time 
              ORDER BY b.time desc 
              FETCH FIRST 1 ROW ONLY ) b
ORDER BY a.time;

基本上,这会从 table B 中为 table A 中的每一行找到最近的非空值。

SQL*服务器解决方案

这是翻译成 SQL*Server:

OUTER APPLY 语法
with table_a ( time, value ) as
  ( SELECT '9:00', 3.4 UNION ALL
    SELECT '9:01', 5.0 UNION ALL
    SELECT '9:02', 5.3 UNION ALL
    SELECT '9:03', 5.3 UNION ALL
    SELECT '9:04', 5.3 ),
table_b ( time, value ) as 
  ( SELECT '9:00', 4 UNION ALL
    SELECT '9:01', 4.1 UNION ALL
    SELECT '9:04', 4.7 )
SELECT a.time, b.value
FROM   table_a a OUTER APPLY ( 
        SELECT * FROM table_b b 
        WHERE b.time <= a.time 
        ORDER BY b.time desc 
        OFFSET 0 ROWS
        FETCH NEXT 1 ROWS ONLY ) b
ORDER BY a.time;