Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 按id和每个日期的最近日期联接表_Sql_Date_Dataset - Fatal编程技术网

Sql 按id和每个日期的最近日期联接表

Sql 按id和每个日期的最近日期联接表,sql,date,dataset,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

我有两张桌子:

表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,在另一个表中取最接近的测量日期,并将其排成一行。接近的东西

 SELECT *
 FROM table1 a
 INNER JOIN table2 b
 ON a.id = b.id
       AND <date from a is closest date from b>
选择*
来自表1 a
内连接表2b
在a.id=b.id上
及

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

如果您有窗口函数,请使用
行编号()

我使用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

在标准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;
然后,您可以返回到
表2
,以从该行获取更多信息


以上是通用SQL(不一定是标准SQL)。日期/时间函数往往是每个数据库特有的;因此,
-
可能不适用于这种差异。并非所有数据库都支持只获取前1行,但几乎所有数据库都支持某种机制来完成相同的操作。

您的rdbms是什么?Sql Server、postgres、oracle?Sql Server很抱歉,我在postedI之后不久就被卷入了一些事情。我不认为这在所有情况下都会起作用:当两个表中的组的行数不同时会发生什么情况(如示例所示)?或者当有非常古老的日期和一些相近的日期时?(例如,在表2中,除了2017年的一个日期外,所有日期都在1999年,该日期应与表1中的记录相匹配)@Damiano Ohh我明白你的意思。