编写SQL查询获取仅含最新日期的数据,附相关表结构
获取包含最新日期的交易数据SQL查询方案
咱们先明确下两张表的结构,方便理解需求:
表结构
Table: User
| id | name | contact |
|---|---|---|
| 101 | John | 123121 |
| 102 | Jake | 123122 |
| 103 | Mia | 123123 |
| 104 | Mike | 123124 |
| 105 | Drake | 123125 |
| 106 | Jonas | 123126 |
Table: Transaction
| billno | billdate | user_id |
|---|---|---|
| A001 | 01/01/18 | 101 |
| A002 | 01/01/18 | 102 |
| A003 | 01/01/18 | 103 |
| A004 | 01/02/18 | 101 |
| A005 | 01/02/18 | 105 |
| A006 | 01/02/18 | 102 |
| A007 | 01/03/18 | 105 |
接下来给你两种常用的查询方案,适配不同的数据库场景:
方案1:子查询获取全局最新日期(通用所有SQL数据库)
这个方法逻辑简单直接,先找到交易表中的最新日期,再筛选出该日期的所有交易记录,最后关联用户表拿到对应的用户信息:
SELECT u.id, u.name, u.contact, t.billno, t.billdate FROM User u JOIN Transaction t ON u.id = t.user_id WHERE t.billdate = (SELECT MAX(billdate) FROM Transaction);
执行后会返回所有在01/03/18(当前数据的最新日期)的交易,也就是A007这条记录对应的用户Drake的信息。
方案2:窗口函数(适用于支持窗口函数的数据库,如MySQL8.0+、PostgreSQL、SQL Server等)
如果你的数据库支持窗口函数,也可以用这种方式。这里分两种场景:
全局最新日期记录的窗口函数写法
SELECT u.id, u.name, u.contact, t.billno, t.billdate FROM User u JOIN ( SELECT billno, billdate, user_id, MAX(billdate) OVER () AS latest_date FROM Transaction ) t ON u.id = t.user_id WHERE t.billdate = t.latest_date;
每个用户的最新交易记录(扩展需求)
如果你的实际需求是获取每个用户自己的最新交易,而不是全表的最新日期,那可以用ROW_NUMBER()窗口函数:
SELECT id, name, contact, billno, billdate FROM ( SELECT u.id, u.name, u.contact, t.billno, t.billdate, ROW_NUMBER() OVER (PARTITION BY u.id ORDER BY STR_TO_DATE(t.billdate, '%m/%d/%y') DESC) AS rn FROM User u JOIN Transaction t ON u.id = t.user_id ) AS sub_query WHERE rn = 1;
这个查询会给每个用户的交易按日期倒序编号,取编号为1的那条,也就是该用户的最新交易记录。
注意事项
如果你的billdate字段是字符串类型(不是数据库原生的日期类型),直接用字符串比较可能会出错,比如12/31/23和01/01/24字符串排序会认为前者更大。这时候需要先把字符串转成日期类型再比较,比如MySQL中可以用STR_TO_DATE()函数,修改后的查询如下:
SELECT u.id, u.name, u.contact, t.billno, t.billdate FROM User u JOIN Transaction t ON u.id = t.user_id WHERE STR_TO_DATE(t.billdate, '%m/%d/%y') = (SELECT MAX(STR_TO_DATE(billdate, '%m/%d/%y')) FROM Transaction);
内容的提问来源于stack exchange,提问作者Hasics
相关产品推荐
相关产品推荐

