查询同一用户最新的一条交易记录
·
一、背景介绍
先说下遇到的业务场景:需要根据用户号获取该用户交易时间最新的一条交易记录。那么实现方式有几种,每种之间有什么区别呢?效率又有何不同?
二、解决方案
1. 实现步骤
- ① 查询每个用户的最新一条有效交易记录
- ② 通过该条交易记录的id关联到支付数据,筛选出支付成功的数据
2. 实现方案
1) 子查询
SELECT p.*
FROM t_payment_table p
WHERE p.transaction_id = (
SELECT t.transaction_id
FROM t_payment_table t
WHERE u.user_id = p.user_id
AND t.transaction_status = '有效'
ORDER BY t.transaction_time DESC
LIMIT 1
)
AND p.payment_status = '成功'
2) 连接表
SELECT p.*
FROM t_transaction_table t1
LEFT JOIN t_transaction_table t2
ON t1.user_id = t2.user_id
AND t1.transaction_time < t2.transaction_time
-- 过滤有效状态的交易记录
AND t2.transactioin_status = '有效'
JOIN t_payment_table p in t1.transaction_id = p.transaction_id
WHERE t2.user_id IS NULL
-- 确保t1也是有效状态
AND t1.transaction_status = '有效'
AND p.payment_status = '有效'
3) 窗口函数
WITH latest_transactions AS (
SELECT *.
ROW_NUMBER() OVER (PARTIOTION BY user_id ORDER BY transaction_time DESC) AS rn
FROM t_payment_table
WHERE transaction_status = '有效'
)
SELECT p.*
FROM latest_transactions lt
JOIN t_payment_table p on lt.transaction_id = p.transaction_id
WHERE lt.rn = 1
AND p.payment_status = '成功';
3. 3种高级查询方式的区别
| 子查询 | 连接表 | 窗口函数 | |
| 定义 | 嵌套在其他查询中的查询,用于获取数据并将其作为外层查询的条件或数据源 | 通过关联字段将两个或多个表合并,形成新数据集 | 在不使用分组的情况下对数据进行分区和排序计算,保留所有行数据 |
| 核心功能 | 标量子查询(如=, >, <)、列子查询(IN, ANY, ALL)、相关子查询(如EXISTS)等 | 内连接、左连接、右连接、全外连接 | 分区(PARTITION BY)、排序(ORDER BY) |
| 应用场景 | 复杂条件筛选 分层数据处理 |
多表数据整合 关系分析 |
排名分析 逐步计算 |
| 特点 | 执行顺序:外层查询先执行子查询,再应用结果。 性能:可能多次执行子查询,需优化(如索引)。 |
执行顺序:大表驱动小表原则(用EXPLAIN验证)。 性能优化:关联字段需建立索引。 |
保留行数据:与GROUP BY不同,窗口函数不聚合数据。 复杂计算:可替代部分子查询和连接。 |
| 数据处理方式 | 外层查询依赖子查询结果 | 通过索引优化关联效率 | 不聚合数据,保留所有行 |
4. 实现方式对比
- 子查询:适用于大多数数据库,但可能在大数据量时效率较低。
- 连接表:适用于所有数据库,但可能在大数据量时效率较低。
- 窗口函数:适用于支持窗口函数的数据库(如PostgreSQL、SQL Server),效率较高。
更多推荐
所有评论(0)