Skip to main content

FROM 子句

FROM 子句指定查询的数据源。从逻辑上讲,FROM 子句是查询开始执行的位置。它可以包含单个表、多个连接的表或子查询节点中的另一个 SELECT 查询。

FROM 子句从逗号分隔的表引用列表中的一个或多个表派生出一个表。

以下是 FROM 子句的基本句法:

FROM table_reference [, table_reference [, ...]]

table_reference 可以是表名、派生表(如子查询)、JOIN 结构或复杂组合。

如果指定了多个 source,结果是所有 source 的笛卡尔积(即交叉连接)。 FROM 列表的结果是一个中间虚拟表,然后可以通过 WHEREGROUP BYHAVING 子句进行转换,最后得到整个表表达式的结果。

Joined table

连接表是根据特定连接类型的规则从另外两个(实际或派生的)表派生出的表。可以使用内连接、外连接和交叉连接。

句法:

t1 join_type t2 [ join_condition ]

子查询

指定派生表的子查询必须用括号括起来,并且必须分配表别名。

句法:

FROM (SELECT * FROM table1) AS alias_name

此示例等效于 FROM table1 AS alias_name

表函数

表函数生成一组由基本数据类型(标量类型)或复合数据类型(表行)组成的行。它们类似于查询的 FROM 子句中的表、视图或子查询。表函数返回的列可以像表列、视图或子查询列一样包含在 SELECTJOINWHERE 子句中。

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;