类别:

查询语法

横向联接

FROM 子句中,LATERAL 关键字允许内联视图引用该内联视图之前的表表达式中的列。

横向联接的行为更像相关子查询,而不像大多数 JOINs。横向联接的行为就像服务器执行了类似于以下内容的循环:

for each row in left_hand_table LHT:
    execute right_hand_subquery RHS using the values from the current row in the LHT
Copy

与非横向联接的输出不同,横向联接的输出仅包括从内联视图生成的行。左侧的行不需要联接到右侧,因为左侧的行已通过传递到内联视图来考虑。

本主题内容:

语法

SELECT ...
FROM <left_hand_table_expression>, LATERAL ( <inline_view> )
...
Copy
left_hand_table_expression

这是行的源,例如:

  • 表。

  • 视图。

  • 子查询。

  • 表函数。

  • 先前联接的结果。

inline_view

inline_view 可以是:

  • 内联视图(在语句中定义的视图,仅在语句的持续时间内有效)。

  • 子查询。

  • 表函数(内置表函数,如 FLATTEN 或用户定义的表函数 [UDTF])。

inline_view 不能是表。

使用说明

  • 关键字 LATERAL 后面的内联视图只能引用内联视图本身以及 FROM 子句内联视图左侧的表中的列。

    SELECT *
        FROM table_reference_me, LATERAL (...), table_do_not_reference_me ...
    
    Copy
  • 尽管内联视图通常引用 left_hand_table_expression 中的列,但并不要求这样做。

  • 正如 INNER JOIN 语法可以使用逗号或单词“ INNER JOIN”一样,横向联接也可以使用逗号或单词 INNER JOIN。

  • 不能在横向表函数(SQL UDTF 除外)中指定 ON、USING 或 NATURAL JOIN 子句,也不能在表函数(SQL UDTF 除外)的外部横向联接中指定 ON、USING 或 NATURAL JOIN 子句。

    有关详细信息,请参阅 JOIN 主题中的使用说明

示例

此示例使用如下所示的数据:

CREATE TABLE departments (department_id INTEGER, name VARCHAR);
CREATE TABLE employees (employee_ID INTEGER, last_name VARCHAR, 
                        department_ID INTEGER, project_names ARRAY);
Copy
INSERT INTO departments (department_ID, name) VALUES 
    (1, 'Engineering'), 
    (2, 'Support');
INSERT INTO employees (employee_ID, last_name, department_ID) VALUES 
    (101, 'Richards', 1),
    (102, 'Paulson',  1),
    (103, 'Johnson',  2); 
Copy

基本示例

此示例演示带有子查询的 LATERAL JOIN。

SELECT * 
    FROM departments AS d, LATERAL (SELECT * FROM employees AS e WHERE e.department_ID = d.department_ID) AS iv2
    ORDER BY employee_ID;
+---------------+-------------+-------------+-----------+---------------+---------------+
| DEPARTMENT_ID | NAME        | EMPLOYEE_ID | LAST_NAME | DEPARTMENT_ID | PROJECT_NAMES |
|---------------+-------------+-------------+-----------+---------------+---------------|
|             1 | Engineering |         101 | Richards  |             1 | NULL          |
|             1 | Engineering |         102 | Paulson   |             1 | NULL          |
|             2 | Support     |         103 | Johnson   |             2 | NULL          |
+---------------+-------------+-------------+-----------+---------------+---------------+
Copy

将 LATERAL 与 FLATTEN() 结合使用的示例

此示例演示横向联接如何使用 FLATTEN 返回的内联视图:

SELECT * FROM table1, LATERAL FLATTEN(...);
Copy

首先,更新员工表以包含 FLATTEN 可以操作的 ARRAY 数据:

UPDATE employees SET project_names = ARRAY_CONSTRUCT('Materialized Views', 'UDFs') 
    WHERE employee_ID = 101;
UPDATE employees SET project_names = ARRAY_CONSTRUCT('Materialized Views', 'Lateral Joins')
    WHERE employee_ID = 102;
Copy

其次,执行一个查询,该查询使用 FLATTEN 并包含对其前面表中某列的引用:

SELECT emp.employee_ID, emp.last_name, index, value AS project_name
    FROM employees AS emp, LATERAL FLATTEN(INPUT => emp.project_names) AS proj_names
    ORDER BY employee_ID;
+-------------+-----------+-------+----------------------+
| EMPLOYEE_ID | LAST_NAME | INDEX | PROJECT_NAME         |
|-------------+-----------+-------+----------------------|
|         101 | Richards  |     0 | "Materialized Views" |
|         101 | Richards  |     1 | "UDFs"               |
|         102 | Paulson   |     0 | "Materialized Views" |
|         102 | Paulson   |     1 | "Lateral Joins"      |
+-------------+-----------+-------+----------------------+
Copy

显示两种联接语法的示例

以下 SQL 语句是等效的,并且产生相同的输出(下面只显示了一次输出)。下面的第一条 SQL 语句在关键字 LATERAL 前使用逗号,而第二条 SQL 语句使用关键字 INNER JOIN。

SELECT * 
    FROM departments AS d, LATERAL (SELECT * FROM employees AS e WHERE e.department_ID = d.department_ID) AS iv2
    ORDER BY employee_ID;
Copy
SELECT * 
    FROM departments AS d INNER JOIN LATERAL (SELECT * FROM employees AS e WHERE e.department_ID = d.department_ID) AS iv2
    ORDER BY employee_ID;
+---------------+-------------+-------------+-----------+---------------+---------------+
| DEPARTMENT_ID | NAME        | EMPLOYEE_ID | LAST_NAME | DEPARTMENT_ID | PROJECT_NAMES |
|---------------+-------------+-------------+-----------+---------------+---------------|
|             1 | Engineering |         101 | Richards  |             1 | NULL          |
|             1 | Engineering |         102 | Paulson   |             1 | NULL          |
|             2 | Support     |         103 | Johnson   |             2 | NULL          |
+---------------+-------------+-------------+-----------+---------------+---------------+
Copy
语言: 中文