FROM 子句
FROM
子句指定查询的数据源。从逻辑上讲,FROM
子句是查询开始执行的位置。它可以包含单个表、多个连接的表或子查询节点中的另一个 SELECT 查询。
FROM
子句从逗号分隔的表引用列表中的一个或多个表派生出一个表。
以下是 FROM
子句的基本句法:
FROM table_reference [, table_reference [, ...]]
table_reference
可以是表名、派生表(如子查询)、JOIN
结构或复杂组合。
如果指定了多个 source,结果是所有 source 的笛卡尔积(即交叉连接)。 FROM
列表的结果是一个中间虚拟表,然后可以通过 WHERE
、GROUP BY
和 HAVING
子句进行转换,最后得到整个表表达式的结果。
Joined table
连接表是根据特定连接类型的规则从另外两个(实际或派生的)表派生出的表。可以使用内连接、外连接和交叉连接。
句法:
t1 join_type t2 [ join_condition ]
子查询
指定派生表的子查询必须用括号括起来,并且必须分配表别名。
句法:
FROM (SELECT * FROM table1) AS alias_name
此示例等效于 FROM table1 AS alias_name
。
表函数
表函数生成一组由基本数据类型(标量类型)或复合数据类型(表行)组成的行。它们类似于查询的 FROM
子句中的表、视图或子查询。表函数返回的列可以像表列、视图或子查询列一样包含在 SELECT
、JOIN
或 WHERE
子句中。
LATERAL
子查询
FROM
中的子查询前可放置 LATERAL
关键字。这允许子查询引用前面的 FROM
项提供的列。如果没有 LATERAL
,每一个子查询将被独立计算,并且因此不能交叉引用任何其他 FROM
项。
要创建 LATERAL
子查询,请在内部子查询的 SELECT
语句前直接使用 LATERAL
关键字。
下面的查询包含两个 LATERAL
子查询。第一个 LATERAL
子查询计算最大销售额,并将结果缓存在派生表 max_sale
中。第二个 LATERAL
子查询根据派生表中的最大销售金额查找客户名称,并将结果存储在另一个派生表 max_sale_customer
中。
SELECT
salesperson.name,
max_sale.amount,
max_sale_customer.customer_name
FROM
salesperson,
-- 计算最大销售额并将其缓存到派生表中
LATERAL
(SELECT MAX(amount) AS amount
FROM all_sales
WHERE all_sales.salesperson_id = salesperson.id)
AS max_sale,
-- 查找客户,重用缓存的最大销售额
LATERAL
(SELECT customer_name
FROM all_sales
WHERE all_sales.salesperson_id = salesperson.id
AND all_sales.amount =
-- 缓存的最大销售额
max_sale.amount)
AS max_sale_customer;
可以将 LEFT 连接应用到 LATERAL
子查询,以确保源行出现在查询结果中(即使子查询不生成它们的行)。
例如,可以将上述查询改写为 LEFT 连接 LATERAL 子查询:
SELECT
salesperson.name,
max_sale.amount,
max_sale.customer_name
FROM
salesperson left join
-- 同时找到最大尺寸和客户
LATERAL
(SELECT amount, customer_name
FROM all_sales
WHERE all_sales.salesperson_id = salesperson.id
ORDER BY amount DESC LIMIT 1)
AS max_sale on true;