首页 > 解决方案 > 应用联接,按日期列排序并选择其中一个列值不为空的第一行

问题描述

我在 Postgres DB 中有两个表(表 A 和表 B)。

两者都有共同的“id”列。表 A 有一列称为“id”,表 B 有三列:“id, date, value($)”。对于表 A 的每个“id”,表 B 中存在多行,格式如下 - (id, date, value)。

例如,对于“id”为 1 的表 A,如果表 B 中存在以下行:

我想提取最近的日期非空值。例如对于 id - 1,结果应该是 202。如果需要更多信息,请分享您的想法或让我知道。

标签: postgresqlpostgresql-9.3

解决方案


您可能非常想要内部联接,而不是外部联接。如果您在 table1 中有一个在 table2 中不存在的 id 或者只有空值,那么日期和值都将为 NULL。这是由于外部联接的工作方式。它的意思是,如果右侧表中没有任何内容与 ON 条件匹配,则为该表中的每一列返回 NULL。所以

with mapping as 
     (select distinct table1.id
           , table2.value
           , table2.date
           , row_number() over (partition by table1.id order by table2.date desc nulls last) as row_number
        from table1
        join table2 on table2.id=table1.id and table2.value is not null
     )
select * 
  from mapping 
 where row_number = 1; 

请参阅此处的每个示例。您的查询有效,因为您的所有测试数据都满足 ON 条件的第一个条件。您确实需要无法查看查询内容的测试数据。
注意: DATE 和 VALUE 对于列名来说是非常糟糕的选择。两者都是SQL 标准保留字,虽然不是 Postgres。此外 DATE 是 Postgres 数据类型。列名称与数据类型相同会导致混淆。


推荐阅读