2014-01-18 65 views
1

我有一个关系:最接近的值

CREATE TABLE mag (
pg_id serial, 
nt numeric, 
time numeric 
); 

,其中包含一些元组:

INSERT INTO mag 
(nt, time) 
VALUES (10,100), (11,200), (12,300), (13,400), (14,500); 

我也有另一种关系:

CREATE TABLE gps (
pg_id serial, 
x numeric, 
y numeric, 
time numeric 
); 

它也包含了一些元组:

INSERT INTO gps 
(x, y, time) 
VALUES (500,500,120), (600,600,180), (700,700,190), (800,800,320), (900,900,800); 

我想加入表格。 mag关系中的每个元组应该连接到time字段中具有最接近的值(绝对值的最小差异)的gps关系中的元组。

美中不足的,当然,是真实世界的关系都包含几千元组,所以额外的荣誉将授予查询速度。

回答

0

试试这个:

SELECT m.pg_id, m.nt, m.time mag_time, 
g.* 
FROM (
SELECT m.pg_id, m.time, 
     CASE 
      WHEN min(g2.time) is null 
      THEN max(g1.time) 
      WHEN max(g1.time) is null 
      THEN min(g2.time) 
      WHEN 
      m.time - max(g1.time) 
      < 
      min(g2.time) - m.time 
      THEN max(g1.time) 
      ELSE min(g2.time) 
     END join_time 
    FROM mag m 
    LEFT JOIN gps g1 
    ON m.time >= g1.time 
    LEFT JOIN gps g2 
    ON m.time <= g2.time 
    GROUP BY m.pg_id, m.time 
) AS j 
LEFT JOIN mag m 
ON j.pg_id = m.pg_id 
LEFT JOIN gps g 
ON j.join_time = g.time 
; 

演示:http://www.sqlfiddle.com/#!15/33fc0/17

gps.time列的索引必须创建以加快此查询。
我认为mag.pg_id是主键,所以此列的索引已经存在,
如果没有,则此列也必须建立索引。

+0

这似乎从mag关系返回4条记录,而不是所有5个元组。这是你的预期吗? – Joebocop

+0

我已更正查询并更新了答案。 – krokodilko

+0

对不起,延误了。我回到办公室,现在正在检查您的修订解决方案。再次感谢您的意见。 – Joebocop