加入包含多条记录的第二个表,取最新的
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 对实体查询进行分组,以通过加入表来获取具有最新时间戳的一条记录