暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Lateral 查询详解:概念、适用场景与普通 JOIN 的区别

PawSQL 2025-04-17
317
1. 什么是Lateral查询?

Lateral查询(也称为横向关联查询)是一种特殊的子查询,允许子查询中引用外层查询的列(即关联引用),并在执行时逐行对外层查询的每一行数据执行子查询。  语法上通常使用关键字 LATERAL
(部分数据库如PostgreSQL支持),或通过特定语法隐式实现(如Oracle的CROSS APPLY
/OUTER APPLY
)。

示例

    -- 显式LATERAL(PostgreSQL)
    SELECT t1.id, t2.amount
    FROM t1,
    LATERAL (SELECT amount FROM t2 WHERE t2.id = t1.id) t2;


    -- 隐式实现(Oracle/SQL Server)
    SELECT t1.id, t2.amount
    FROM t1
    CROSS APPLY (SELECT amount FROM t2 WHERE t2.id = t1.id) t2;

    2. Lateral查询的适用场景

    Lateral查询主要用于以下场景:

    场景1:逐行依赖计算

    当子查询需要基于外层查询的当前行动态计算时,必须使用Lateral。  案例:计算每个用户的最近一笔订单金额。  

      SELECT u.user_id, o.order_amount
      FROM users u,
      LATERAL (
          SELECT amount AS order_amount
          FROM orders
          WHERE user_id = u.user_id
          ORDER BY order_date DESC
          LIMIT 1  -- 每行用户只取最新订单
      ) o;

      说明  普通JOIN无法实现“每行限制结果”(如LIMIT 1
      ),而Lateral子查询会为每个user_id
      单独执行。

      场景2:JSON/数组展开

      解析嵌套数据结构(如JSON数组、XML)时,需将数组元素展开为多行。  案例:展开用户标签数组。  

        SELECT u.user_id, tag.tag_name
        FROM users u,
        LATERAL jsonb_array_elements(u.tags) AS tag(tag_name);

        说明  jsonb_array_elements
        函数为每个用户的标签数组生成多行,依赖外层查询的u.tags
        字段。

        场景3:复杂聚合与过滤

        当聚合逻辑需要依赖外层条件时,Lateral比普通JOIN更直观。  案例:统计每个用户消费金额超过平均值的订单数。  

          SELECT u.user_id, COUNT(o.order_id) AS high_value_orders
          FROM users u,
          LATERAL (
              SELECT order_id
              FROM orders
              WHERE user_id = u.user_id AND amount > (
                  SELECT AVG(amount) FROM orders WHERE user_id = u.user_id
              )
          ) o
          GROUP BY u.user_id;

          3. Lateral查询 vs 普通JOIN

          特性Lateral查询普通JOIN(LEFT JOIN/INNER JOIN)
          执行逻辑逐行执行子查询,依赖外层当前行数据先完成所有表关联,再过滤或聚合
          关联引用子查询可引用外层列子查询不能直接引用外层列(需通过JOIN条件)
          性能可能较慢(N次子查询)通常更快(单次扫描+哈希连接)
          适用操作支持LIMIT
          、窗口函数等逐行操作
          无法在JOIN中直接使用LIMIT
          典型语法LATERAL
          CROSS APPLY
          OUTER APPLY
          JOIN ... ON
          WHERE
          4. 何时选择Lateral查询?
          • ✅ 需要逐行处理(如LIMIT
            、窗口函数)。  

          • ✅ 子查询依赖外层列且无法通过普通JOIN条件表达。  

          • ✅ 展开嵌套数据结构(JSON/数组)。  

          • ❌ 大数据量场景慎用(可能性能较差)。  

          5. 总结

          • Lateral查询通过逐行执行子查询,解决了普通JOIN无法处理的动态关联问题。  

          • 核心优势:支持复杂逐行逻辑(如LIMIT
            、JSON展开)。  

          • 代价:可能因N次子查询导致性能下降,需结合优化器规则(如PawSQL的解关联)权衡使用。  

          在实际应用中,优先尝试用普通JOIN优化,仅在必要时使用Lateral。

          文章转载自PawSQL,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

          评论