[英]LATERAL syntax in MySQL - Is it just to say that "the left table" is executed first so that the next one can reference it?
What does " A derived table cannot contain references to other tables of the same SELECT " mean? “派生表不能包含对同一 SELECT 的其他表的引用”是什么意思? I looked it up in the MySQL documentation
我在 MySQL 文档中查找了它
SELECT
salesperson.name,
max_sale.amount,
max_sale_customer.customer_name
FROM
salesperson,
-- calculate maximum size, cache it in transient derived table max_sale
LATERAL
(SELECT MAX(amount) AS amount
FROM all_sales
WHERE all_sales.salesperson_id = salesperson.id)
AS max_sale,
-- find customer, reusing cached maximum size
LATERAL
(SELECT customer_name
FROM all_sales
WHERE all_sales.salesperson_id = salesperson.id
AND all_sales.amount =
-- the cached maximum size
max_sale.amount)
AS max_sale_customer;
A derived table cannot contain references to other tables of the same SELECT (use a LATERAL derived table for that; see Section 13.2.11.9, “Lateral Derived Tables”)派生表不能包含对同一 SELECT 的其他表的引用(为此使用 LATERAL 派生表;请参阅第 13.2.11.9 节,“横向派生表”)
The key to understanding this is in the manual you have read:理解这一点的关键在于您已阅读的手册:
Derived tables must be constant over the query's duration, not contain references to columns of other FROM clause tables.
派生表在查询期间必须保持不变,不包含对其他 FROM 子句表的列的引用。
That is, think of the derived table as running at the initial time of the query, before any rows from the joined tables have been read.也就是说,将派生表视为在查询的初始时间运行,在连接表中的任何行被读取之前。 If the derived table subquery includes any references to joined tables, then the result of the derived table would depend on data read from those tables.
如果派生表子查询包括对连接表的任何引用,则派生表的结果将取决于从这些表中读取的数据。 Can conflicts with the requirement that a derived table be constant.
可能与派生表为常量的要求相冲突。
LATERAL
changes that. LATERAL
改变了这一点。 It ensures that the derived table is evaluated later, after the query begins to read rows from the joined tables.它确保在查询开始从联接表中读取行之后,稍后评估派生表。
PS: The comment from jarlh above is not strictly correct. PS:上面 jarlh 的评论并不完全正确。 It is recommended for other reasons to use explicit
JOIN
syntax (eg it supports outer joins and so on), but it's not required for the sake of LATERAL
.出于其他原因,建议使用显式
JOIN
语法(例如,它支持外连接等),但对于LATERAL
而言,它不是必需的。
The documentation ( here ) attempts to explain that if you start with a correlated subquery
inside the select list
then it IS possible to refer to the table in the from clause
eg:文档( 此处)试图解释,如果您从
select list
的correlated subquery
开始,则可以在from clause
中引用该表,例如:
SELECT salesperson.name, -- find maximum sale size for this salesperson (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id =salesperson.id) AS amount FROM
salesperson;
In the query above you can see that the from table is salesperson but in the correlated subquery
you CAN also refer to salesperson .在上面的查询中,您可以看到 from 表是salesperson ,但在
correlated subquery
中,您也可以引用salesperson 。 The correlation
is that the subquery is being executed row by row through the resultset, with each iteration of that subquery using the salesperson.id as input to the where clause. correlation
是子查询通过结果集逐行执行,该子查询的每次迭代都使用salesperson.id作为 where 子句的输入。 (By the way, this "row by row" effect is often why correlated subqueries
can be a cause of slowness in queries.) (顺便说一下,这种“逐行”效应通常是为什么
correlated subqueries
会导致查询速度变慢。)
However it is not permitted in traditional derived tables
, found in the from clause
, to use a correlation
like the one seen above.但是,在
from clause
中的传统derived tables
中,不允许使用上述correlation
。 So the example below will fail because it tries to use a correlation
to salesperson that isn't allowed:因此,下面的示例将失败,因为它尝试使用不允许的与销售人员的
correlation
:
SELECT salesperson.name, max_sale.amount, max_sale_customer.customer_name FROMsalesperson, -- calculate maximum size, cache it in transient derived table max_sale (SELECT MAX(amount) AS amount FROM all_sales WHERE all_sales.salesperson_id =
salesperson.id) AS max_sale AS max_sale_customer;
As the documentation states this will result in an error:正如文档所述,这将导致错误:
ERROR 1054 (42S22): Unknown column 'salesperson.id' in 'where clause'
BUT , with the addition of support for LATERAL
it is possible to to replace correlated subqueries
that we once used in the select clause
with lateral subqueries
as these DO support the ability to refer to other tables referenced in the from clause
.但是,通过增加对
LATERAL
的支持,可以将我们曾经在select clause
中使用的correlated subqueries
替换为lateral subqueries
,因为这些子查询确实支持引用from clause
中引用的其他表的能力。 Additionally (which can't be done in a select clause
) one lateral subquery
can refer to the result of any prior lateral subquery
which is a really very useful feature, and this is also shown by the example in the documentation:此外(不能在
select clause
中完成)一个lateral subquery
可以引用任何先前lateral subquery
的结果,这是一个非常有用的功能,文档中的示例也显示了这一点:
SELECT salesperson.name, max_sale.amount, max_sale_customer.customer_name FROM salesperson, -- calculate maximum size, cache it in transient derived table max_sale LATERAL (SELECT MAX(amount) ASamount FROM all_sales WHERE all_sales.salesperson_id = salesperson.id) AS
max_sale, -- find customer, reusing cached maximum size LATERAL (SELECT customer_name FROM all_sales WHERE all_sales.salesperson_id = salesperson.id AND all_sales.amount = -- the cached maximum size
max_sale.amount) -- refers to prior lateral subquery result AS max_sale_customer;
So, conventional derived tables cannot use correlations, lateral subqueries can.因此,传统的派生表不能使用相关性,横向子查询可以。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.