每个日期按ID和最近日期加入表格

时间:2017-11-03 17:45:46

标签: sql date dataset

我有两张桌子:

表1

id      date_measured    value 1

1       01/01/2017       5
1       02/20/2017       6
1       04/01/2017       5
2       03/02/2017       5
2       04/02/2017       3

表2

id      date_measured    value 2

1       01/06/2017       5
1       03/01/2017       6
2       02/01/2017       5
2       03/09/2017       7
2       04/05/2017       4

我想加入它,以便每个id匹配,最接近的日期匹配:

id      date_measured1     value 1      date_measured2      value 2

1       01/01/2017         5            01/06/2017          5
1       02/20/2017         6            03/01/2017          6
2       02/01/2017         5            02/01/2017          5
2       03/02/2017         5            03/09/2017          7
2       04/02/2017         3            04/05/2017          4

等。每个测量日期的每个id的IE采用另一个表中最接近的测量日期并使其成行。

接近的东西
 SELECT *
 FROM table1 a
 INNER JOIN table2 b
 ON a.id = b.id
       AND <date from a is closest date from b>

但我不知道如何做第二部分。有什么建议吗?

2 个答案:

答案 0 :(得分:2)

在标准SQL中,您可以使用相关子查询获取日期:

select t1.*,
       (select t2.date_measured
        from table2 t2
        where t2.id = t1.id
        order by abs(t2.date_measured - t1.date_measured) asc
        fetch first 1 row only
       ) as t2_date_measured
from table1 t1;

然后,您可以加入table2以获取该行的其他信息。

以上是通用SQL(不一定是标准SQL)。日期/时间函数往往是每个数据库特有的;所以-可能不适用于差异。并非所有数据库都支持fetch first 1 row only,但几乎所有数据库都支持执行相同操作的某种机制。

答案 1 :(得分:0)

如果您有窗口功能,请使用ROW_NUMBER()

SQL DEMO我使用postgresql,因此日期函数可能因rdbms而异。

WITH cte as (
    SELECT *, 
           t1.id as t1_id, 
           t1.date_measured as t1_date,
           t1.value1,
           t2.id as t2_id, 
           t2.date_measured as t2_date,
           t2.value2,
           date_part('day', age(t1.date_measured, t2.date_measured)) as days,
           ROW_NUMBER() OVER (PARTITION BY t1.id, t1.date_measured
                              ORDER BY abs(date_part('day', age(t1.date_measured, t2.date_measured)))
                              ) as rn

    FROM table1 t1
    JOIN table2 t2
      ON t1.id = t2.id
)
SELECT *
FROM cte
WHERE rn = 1 
ORDER BY t1_id, t1_date