一尘不染

如何对每个帐户的最后一笔交易进行SQL查询?

sql

假设我有一个表“ transactions”,其中有“ acct_id”,“ trans_date”和“
trans_type”列,我想过滤该表,以便每个账户只有最后一笔交易。显然我可以做类似的事情

SELECT acct_id, max(trans_date) as trans_date  
FROM transactions GROUP BY acct_id;

但后来我失去了trans_type。然后,我可以使用日期和帐户ID的列表进行第二次SQL调用,并取回我的trans_type,但这感觉很笨拙,因为这意味着要么将数据来回发送到sql服务器,要么意味着创建一个临时表。

有没有一种方法可以通过单个查询做到这一点,希望有一个通用方法可以与mysql,postgres,sql-server和oracle一起使用。


阅读 212

收藏
2021-03-17

共1个答案

一尘不染

这是每组最大n查询的示例。这个问题每周都会在StackOverflow上出现几次。除了其他人提供的子查询解决方案之外,这也是我的首选解决方案,该解决方案不使用子查询GROUP BY,或CTE:

SELECT t1.*
FROM transactions t1
LEFT OUTER JOIN transactions t2
  ON (t1.acct_id = t2.acct_id AND t1.trans_date < t2.trans_date)
WHERE t2.acct_id IS NULL;

换句话说,返回一行,使不存在其他具有相同acct_id或更大的行trans_date

此解决方案假定该trans_date值对于给定帐户而言是唯一的,否则可能会发生联系,并且查询将返回所有绑定的行。但这对于其他人提供的所有解决方案也是正确的。

我更喜欢这种解决方案,因为我经常在MySQL上工作,而MySQL的优化GROUP BY效果不是很好。因此,通常证明这种外部联接解决方案具有更好的性能。

2021-03-17