说我有一个表“交易”有列“ACCT_ID”“TRANS_DATE”和“TRANS_TYPE”,我想筛选此表,以便我刚才每个帐户的最后一笔交易。显然,我可以做类似

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

但后来我失去了我TRANS_TYPE。然后,我可以做第二次的SQL调用我的日期和帐户ID的列表,并让我TRANS_TYPE回来,但那种感觉很cludgy因为这意味着无论是发送数据来回的SQL Server或意味着创建临时表。

有没有办法用一个单一的查询,希望一个通用的方法,将与MySQL,Postgres的,SQL-Server和Oracle的工作要做到这一点。

有帮助吗?

解决方案

这是一个最大正每组查询。这个问题来了,每周几次在计算器上。除了由其他人给出的子查询的解决方案,这是我的优选解决方案,其不使用子查询,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,这不优化GROUP BY很好的工作。因此,这外连接的解决方案通常被证明是更好的性能。

其他提示

这工作SQL Server上...

SELECT acct_id, trans_date, trans_type
FROM transactions a
WHERE trans_date = (
   SELECT MAX( trans_date )
   FROM transactions b
   WHERE a.acct_id = b.acct_id
)

尝试此

WITH 
LastTransaction AS
(
    SELECT acct_id, max(trans_date) as trans_date  
    FROM transactions 
    GROUP BY acct_id
),
AllTransactions AS
(
    SELECT acct_id, trans_date, trans_type
    FROM transactions 
)
SELECT *
FROM AllTransactions
INNER JOIN AllTransactions 
    ON AllTransactions.acct_id = LastTransaction.acct_id
    AND AllTransactions.trans_date  = LastTransaction.trans_date
select t.acct_id, t.trans_type, tm.trans_date
from transactions t
inner join (
    SELECT acct_id, max(trans_date) as trans_date  
    FROM transactions 
    GROUP BY acct_id;
) tm on t.acct_id = tm.acct_id and t.trans_date = tm.trans_date
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top