加入包含多条记录的第二个表,取最新的

Posted

技术标签:

【中文标题】加入包含多条记录的第二个表,取最新的【英文标题】:Join with a second table containing multiple records, take the latest 【发布时间】:2017-08-17 05:25:37 【问题描述】:

我有两张桌子:

person_id | name
1            name1
2            name2
3            name3

还有第二张桌子:

person_id | date     | balance
1           2016-03     1200                    ---- \
1           2016-04     700                     ----  > same person
1           2016-05     400                     ---- /
3           2016-05     4000

考虑到 person_id 1 在第二张表上有三条记录,我怎样才能通过获取最新记录来加入第一条记录? (即:余额400,对应日期:2016-05)。

例如:查询输出:

person_id | name    | balance
1           name1     400
2           name2     ---
3           name3     4000

如果可能的话,更喜欢简单而不是解决方案的复杂性

【问题讨论】:

你使用什么数据库引擎? AWS Redshift 是一种具有较少功能的 postregres(如果可能,查询应该与 mysql 兼容) 我删除了不兼容的数据库标签。请标记您真正使用的数据库。 【参考方案1】:

适用于所有数据库引擎的查询是

select t1.name, t2.person_id, t2.balance
from table1 t1
join table2 t2 on t1.person_id = t2.person_id
join
(
    select person_id, max(date) as mdate
    from table2
    group by person_id
) t3 on t2.person_id = t3.person_id and t2.date = t3.mdate

【讨论】:

这是否考虑了在第二张表中找不到记录的情况(例如)?还是我必须用左连接替换您的连接? 如果你总是想要person_id,你必须使用左连接 不,因为当您分组时,您只能选择分组或聚合的列(例如 max()、min()、...) @jurgen d:rigerta提供的答案只有1个加入,你这个他是正确的吗? 不,因为 TOP 1/LIMIT 1 子查询只返回一条记录【参考方案2】:

在任何支持 ANSI 标准窗口函数(其中大多数)的数据库中执行此操作的最佳方法是:

select t1.*, t2.balance
from table1 t1 left join
     (select t2.*,
             row_number() over (partition by person_id order by date desc) as seqnum
      from table2 t2
     ) t2
     on t1.person_id = t2.person_id and seqnum = 1;

【讨论】:

有趣的是只有一个连接的使用,无论如何你认为像这样docs.aws.amazon.com/redshift/latest/dg/…这样使用windows的first_value会有点简化吗? @gio 。 . .唉,first_value() 是窗口函数,不是聚合函数,所以不会减少行数。还是需要子查询和过滤,所以答案是等价的。 好的,谢谢+1!无论如何,我将这个问题标记为每个组最大的问题,因为我认为基本上是同一件事。可悲的是,关于这个问题有很多问题,当在数据库中实现一个简单的 FIRST() 或 LAST() 函数可以解决所有问题时

以上是关于加入包含多条记录的第二个表,取最新的的主要内容,如果未能解决你的问题,请参考以下文章

删除第二个表中不包含的记录

通过 linq 对实体查询进行分组,以通过加入表来获取具有最新时间戳的一条记录

如何加入/子查询第二个表

大查询:加入第二个表中的单个最新行

使用 group by 从一个包含批量记录的表中获取一些统计数据并将结果放入第二个表中

访问数据视图中的第二个表