Sql 按id和每个日期的最近日期联接表
我有两张桌子: 表1Sql 按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
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我明白你的意思。