【问题标题】:Join table by id and nearest date for every date每个日期按 id 和最近日期加入表
【发布时间】:2018-04-16 12:49:31
【问题描述】:

我有 2 张桌子:

表 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>

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

【问题讨论】:

  • 你的 rdbms 是什么? Sql Server、postgres、oracle?
  • Sql server 很抱歉,我发布后不久就被卷入其中

标签: sql date dataset


【解决方案1】:

如果您有窗口功能,请使用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

【讨论】:

  • 我不认为在每种情况下都要工作:当组在两个表中具有不同数量的行(如示例中)时会发生什么?或者当有很多旧日期和几个关闭的时候? (例如,在表2中,您可以在1999年的所有日期除以2017年,即应该与表1中的记录相匹配) span>
  • @ damiano哦,我明白你的意思是附近的。 span>
【解决方案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,但几乎所有数据库都支持某种机制来做同样的事情。

【讨论】:

    猜你喜欢
    • 2019-08-16
    • 2023-03-13
    • 1970-01-01
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多