在MySQL中使用FULL OUTER JOIN组合和展平表

时间:2016-10-29 22:40:20

标签: mysql

我有两个来自两个来源(A和B)的价格更新表,格式如下。这些是源A到毫秒的价格更新:

index,timestamp,origin,product,bid,ask,nexttimestamp
A1,2016-10-18 20:39:25.595,A,Dow,7005.5,7007.5,2016-10-18 20:39:34.701
A2,2016-10-18 20:39:34.701,A,Dow,7005.8,7007.8,2016-10-18 20:39:35.703
A3,2016-10-18 20:39:35.703,A,Dow,7005.5,7007.5,2016-10-18 20:39:38.432
A4,2016-10-18 20:39:38.432,A,Dow,7005.8,7007.8,2016-10-18 20:39:44.055
A5,2016-10-18 20:39:44.055,A,Dow,7005.3,7007.3,2016-10-18 20:39:45.146

这些是源B到毫秒的价格更新:

index,timestamp,origin,product,bid,ask,nexttimestamp
B1,2016-10-18 20:39:21.694,B,Dow,7005.8,7006.8,2016-10-18 20:39:27.987
B2,2016-10-18 20:39:27.987,B,Dow,7005.9,7006.9,2016-10-18 20:39:28.058
B3,2016-10-18 20:39:28.058,B,Dow,7006.0,7007.0,2016-10-18 20:39:39.792
B4,2016-10-18 20:39:39.792,B,Dow,7006.2,7007.2,2016-10-18 20:39:39.868
B5,2016-10-18 20:39:39.868,B,Dow,7006.3,7007.3,2016-10-18 20:39:45.845

我在第一栏中标记了一个索引(A1,B1等)。我需要组合并展平这些表格,以便我可以看到每个来源的现行价格,因为另一个来源的更新。字段'时间戳'和' nexttimestamp'基本上是价格更新有效期的开始时间和结束时间。字段nexttimestamp是通过查找表中相同源的下一个价格更新来创建的。

我需要连接表A和B,其中B中的时间戳大于A中的时间戳并且小于' nexttimestamp'在A中,即如果价格更新有效。我需要做一个显示如下内容的联接:

NULL,                                                                  B1,2016-10-18 20:39:21.694,B,Dow,7005.8,7006.8,2016-10-18 20:39:27.987
A1,2016-10-18 20:39:25.595,A,Dow,7005.5,7007.5,2016-10-18 20:39:34.701,B1,2016-10-18 20:39:21.694,B,Dow,7005.8,7006.8,2016-10-18 20:39:27.987
A1,2016-10-18 20:39:25.595,A,Dow,7005.5,7007.5,2016-10-18 20:39:34.701,B2,2016-10-18 20:39:27.987,B,Dow,7005.9,7006.9,2016-10-18 20:39:28.058
A1,2016-10-18 20:39:25.595,A,Dow,7005.5,7007.5,2016-10-18 20:39:34.701,B3,2016-10-18 20:39:28.058,B,Dow,7006.0,7007.0,2016-10-18 20:39:39.792
A2,2016-10-18 20:39:34.701,A,Dow,7005.8,7007.8,2016-10-18 20:39:35.703,B3,2016-10-18 20:39:28.058,B,Dow,7006.0,7007.0,2016-10-18 20:39:39.792
A3,2016-10-18 20:39:35.703,A,Dow,7005.5,7007.5,2016-10-18 20:39:38.432,B3,2016-10-18 20:39:28.058,B,Dow,7006.0,7007.0,2016-10-18 20:39:39.792
A4,2016-10-18 20:39:38.432,A,Dow,7005.8,7007.8,2016-10-18 20:39:44.055,B3,2016-10-18 20:39:28.058,B,Dow,7006.0,7007.0,2016-10-18 20:39:39.792
A4,2016-10-18 20:39:38.432,A,Dow,7005.8,7007.8,2016-10-18 20:39:44.055,B4,2016-10-18 20:39:39.792,B,Dow,7006.2,7007.2,2016-10-18 20:39:39.868
A4,2016-10-18 20:39:38.432,A,Dow,7005.8,7007.8,2016-10-18 20:39:44.055,B5,2016-10-18 20:39:39.868,B,Dow,7006.3,7007.3,2016-10-18 20:39:45.845
A5,2016-10-18 20:39:44.055,A,Dow,7005.3,7007.3,2016-10-18 20:39:45.146,NULL

我一直在尝试以下查询,但无济于事。

   select main.*, sub.*
    from test as main
    left join test as sub on sub.timestamp > main.timestamp and sub.timestamp < main.nexttimestamp  and sub.origin <> main.origin and sub.product = main.product
    order by main.timestamp ;

1 个答案:

答案 0 :(得分:1)

您可以在MySQL中构建一个完整的外部联接,将LEFT JOIN和RIGHT JOIN与UNION结合使用:

select a.*, b.*
from table_a a
left join table_b b 
  on  b.timestamp > a.timestamp
  and b.timestamp < a.nexttimestamp

union all

select a.*, b.*
from table_a a
right join table_b b 
  on  b.timestamp > a.timestamp
  and b.timestamp < a.nexttimestamp
where a.index is null

在第二部分(RIGHT JOIN)中,您需要IS NULL条件,因为所有其他行已包含在第一部分(LEFT JOIN)中。

如果需要,您可以在ON子句中添加更多条件(例如b.product = a.product)。