一、背景介绍

先说下遇到的业务场景:需要根据用户号获取该用户交易时间最新的一条交易记录。那么实现方式有几种,每种之间有什么区别呢?效率又有何不同?

二、解决方案

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),效率较高。
Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐