如何在SQL Server中查询特定客户的最新交易日期记录
获取每个客户最新交易日期的所有记录
嘿,我来帮你搞定这个SQL查询需求!先明确你的场景:你有一张交易数据表,需要提取每个客户(按Cust_id区分)最新交易日期对应的所有记录——比如Srini的最新交易在2018-05-02,要返回这天的两条记录;Arun的最新交易在2018-05-01,返回这天的两条记录。
原始数据表结构与数据
先把你的表和数据用SQL代码还原出来(方便测试):
CREATE TABLE Transactions ( id INT, Cust_id INT, Name VARCHAR(50), Qty INT, Trans_date DATE ); INSERT INTO Transactions VALUES (1, 101, 'Srini', 10, '2018-05-01'), (2, 101, 'Srini', 20, '2018-05-01'), (3, 102, 'Arun', 100, '2018-05-01'), (4, 102, 'Arun', 200, '2018-05-01'), (5, 101, 'Srini', 10, '2018-05-02'), (6, 101, 'Srini', 30, '2018-05-02');
解决方案1:使用窗口函数(推荐)
SQL Server 2008及以上版本支持窗口函数,这种方法简洁高效,还能轻松处理同一客户同一天有多条交易的场景:
WITH CustomerLatestRank AS ( SELECT *, -- 按客户分组,交易日期降序排名,同一日期的记录排名相同 RANK() OVER (PARTITION BY Cust_id ORDER BY Trans_date DESC) AS DateRank FROM Transactions ) SELECT id, Cust_id, Name, Qty, Trans_date FROM CustomerLatestRank WHERE DateRank = 1 -- 筛选排名为1的记录(即最新日期的所有记录) ORDER BY Cust_id, id;
这里用RANK()而不是ROW_NUMBER()的原因是:如果同一客户在最新日期有多条交易,RANK()会给这些记录都标记为1,而ROW_NUMBER()会给它们分配不同的序号,这样就会漏掉部分记录。如果你的业务中不会出现同一客户同一天多条交易,两种函数都可以,但RANK()更通用。
解决方案2:子查询关联
如果你需要兼容更老的SQL Server版本,或者偏好传统的关联写法,可以用子查询先找出每个客户的最新交易日期,再和原表关联:
SELECT t.id, t.Cust_id, t.Name, t.Qty, t.Trans_date FROM Transactions t INNER JOIN ( -- 先计算每个客户的最大交易日期 SELECT Cust_id, MAX(Trans_date) AS LatestTransDate FROM Transactions GROUP BY Cust_id ) latest ON t.Cust_id = latest.Cust_id AND t.Trans_date = latest.LatestTransDate ORDER BY t.Cust_id, t.id;
最终结果
两种方法都会返回你期望的结果:
id Cust_id Name Qty Trans_date 5 101 Srini 10 2018-05-02 6 101 Srini 30 2018-05-02 3 102 Arun 100 2018-05-01 4 102 Arun 200 2018-05-01
内容的提问来源于stack exchange,提问作者Srinivasan




