A derived table cannot normally refer to (depend on) columns of preceding tables in the same FROM clause. As of MySQL 8.0.14, a derived table may be defined as a lateral derived table to specify that such references are permitted.

派生表通常不能在同一个FROM子句中引用(依赖于)前面表的列。在MySQL 8.0.14中,派生表可以被定义为侧向派生表,以指定这种引用是允许的。

Nonlateral derived tables are specified using the syntax discussed in Section 13.2.11.8, “Derived Tables”. The syntax for a lateral derived table is the same as for a nonlateral derived table except that the keyword LATERAL is specified before the derived table specification. The LATERAL keyword must precede each table to be used as a lateral derived table.

非横向派生表使用13.2.11.8节“派生表”中讨论的语法来指定。侧面派生表的语法与非侧面派生表的语法相同,只是关键字lateral在派生表规范之前指定。横向关键字必须位于每个表之前,才能用作横向派生表。

Lateral derived tables are subject to these restrictions:

横向派生表受以下限制:

  • A lateral derived table can occur only in a FROM clause, either in a list of tables separated with commas or in a join specification (JOININNER JOINCROSS JOINLEFT [OUTER] JOIN, or RIGHT [OUTER] JOIN).

  • 侧面派生表只能出现在FROM子句中,或者出现在用逗号分隔的表列表中,或者出现在连接规范中(join、INNER join、CROSS join、LEFT [OUTER] join或RIGHT [OUTER] join)。

  • If a lateral derived table is in the right operand of a join clause and contains a reference to the left operand, the join operation must be an INNER JOINCROSS JOIN, or LEFT [OUTER] JOIN. 如果侧向派生表位于连接子句的右操作数中,并且包含对左操作数的引用,则连接操作必须是INNER join、CROSS join或left [OUTER] join。

    If the table is in the left operand and contains a reference to the right operand, the join operation must be an INNER JOINCROSS JOIN, or RIGHT [OUTER] JOIN. 如果表在左操作数中,并且包含对右操作数的引用,则连接操作必须是INNER join、CROSS join或right [OUTER] join。

  • If a lateral derived table references an aggregate function, the function's aggregation query cannot be the one that owns the FROM clause in which the lateral derived table occurs.

  • 如果侧派生表引用聚合函数,则该函数的聚合查询不能是包含该侧派生表的FROM子句的聚合查询。

  • Per the SQL standard, a table function has an implicit LATERAL, so it behaves as in MySQL 8.0 versions prior to 8.0.14. However, per the standard, the LATERAL word is not allowed before JSON_TABLE(), even though it is implicit.

  • 根据SQL标准,表函数有一个隐式的LATERAL,所以它的行为就像在8.0.14之前的MySQL 8.0版本中一样。然而,根据标准,LATERAL单词不允许出现在JSON_TABLE()之前,即使它是隐式的。

The following discussion shows how lateral derived tables make possible certain SQL operations that cannot be done with nonlateral derived tables or that require less-efficient workarounds.

下面的讨论展示了侧向派生表如何使某些SQL操作成为可能,这些操作无法用非侧向派生表完成,或者需要更低效率的解决方案。

Suppose that we want to solve this problem: Given a table of people in a sales force (where each row describes a member of the sales force), and a table of all sales (where each row describes a sale: salesperson, customer, amount, date), determine the size and customer of the largest sale for each salesperson. This problem can be approached two ways.

假设我们想要解决这个问题:给定一个表的销售人员(每一行描述一个销售团队的成员),和所有的销售表(每一行描述一个销售:销售人员、客户、金额、日期),确定客户的大小和最大的每个销售人员的销售。有两种方法可以解决这个问题。

First approach to solving the problem: For each salesperson, calculate the maximum sale size, and also find the customer who provided this maximum. In MySQL, that can be done like this:

解决问题的第一个方法:对每个销售人员,计算最大销售规模,并找出提供这个最大销售规模的客户。在MySQL中,可以这样做:

SELECTsalesperson.name,-- find maximum sale size for this salesperson(SELECT MAX(amount) AS amountFROM all_salesWHERE all_sales.salesperson_id = salesperson.id)AS amount,-- find customer for this maximum size(SELECT customer_nameFROM all_salesWHERE all_sales.salesperson_id = salesperson.idAND all_sales.amount =-- find maximum size, again(SELECT MAX(amount) AS amountFROM all_salesWHERE all_sales.salesperson_id = salesperson.id))AS customer_name
FROMsalesperson;

That query is inefficient because it calculates the maximum size twice per salesperson (once in the first subquery and once in the second).

该查询效率很低,因为它计算每个销售人员的最大大小两次(一次在第一个子查询中,一次在第二个子查询中)。

We can try to achieve an efficiency gain by calculating the maximum once per salesperson and “caching” it in a derived table, as shown by this modified query:

我们可以尝试通过计算每个销售人员的最大值并将其“缓存”到派生表中来获得效率收益,如修改后的查询所示:

SELECTsalesperson.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 amountFROM all_salesWHERE all_sales.salesperson_id = salesperson.id)AS max_sale,-- find customer, reusing cached maximum size(SELECT customer_nameFROM all_salesWHERE all_sales.salesperson_id = salesperson.idAND all_sales.amount =-- the cached maximum sizemax_sale.amount)AS max_sale_customer;

However, the query is illegal in SQL-92 because derived tables cannot depend on other tables in the same FROM clause. Derived tables must be constant over the query's duration, not contain references to columns of other FROM clause tables. As written, the query produces this error:

但是,在SQL-92中查询是非法的,因为派生表不能依赖于同一FROM子句中的其他表。派生表必须在查询期间保持不变,不包含对其他FROM子句表列的引用。如上所述,查询产生如下错误:

ERROR 1054 (42S22): Unknown column 'salesperson.id' in 'where clause'

In SQL:1999, the query becomes legal if the derived tables are preceded by the LATERAL keyword (which means “this derived table depends on previous tables on its left side”):

在SQL:1999中,如果派生表前面有LATERAL关键字(这意味着“这个派生表依赖于它左边的前一个表”),则查询是合法的:

SELECTsalesperson.name,max_sale.amount,max_sale_customer.customer_name
FROMsalesperson,-- calculate maximum size, cache it in transient derived table max_saleLATERAL(SELECT MAX(amount) AS amountFROM all_salesWHERE all_sales.salesperson_id = salesperson.id)AS max_sale,-- find customer, reusing cached maximum sizeLATERAL(SELECT customer_nameFROM all_salesWHERE all_sales.salesperson_id = salesperson.idAND all_sales.amount =-- the cached maximum sizemax_sale.amount)AS max_sale_customer;

A lateral derived table need not be constant and is brought up to date each time a new row from a preceding table on which it depends is processed by the top query.

横向派生表不需要是常量,每当top查询处理它所依赖的前一个表中的新行时,就会更新它。

Second approach to solving the problem: A different solution could be used if a subquery in the SELECT list could return multiple columns:

解决问题的第二种方法:如果SELECT列表中的子查询可以返回多个列,则可以使用不同的解决方案:

SELECTsalesperson.name,-- find maximum size and customer at same time(SELECT amount, customer_nameFROM all_salesWHERE all_sales.salesperson_id = salesperson.idORDER BY amount DESC LIMIT 1)
FROMsalesperson;

That is efficient but illegal. It does not work because such subqueries can return only a single column:

这是有效的,但却是非法的。它不能工作,因为这样的子查询只能返回单个列:

ERROR 1241 (21000): Operand should contain 1 column(s)

One attempt at rewriting the query is to select multiple columns from a derived table:

重写查询的一种尝试是从派生表中选择多个列:

SELECTsalesperson.name,max_sale.amount,max_sale.customer_name
FROMsalesperson,-- find maximum size and customer at same time(SELECT amount, customer_nameFROM all_salesWHERE all_sales.salesperson_id = salesperson.idORDER BY amount DESC LIMIT 1)AS max_sale;

However, that also does not work. The derived table is dependent on the salesperson table and thus fails without LATERAL:

然而,这也不起作用。派生的表依赖于销售人员表,因此没有LATERAL就失败了:

ERROR 1054 (42S22): Unknown column 'salesperson.id' in 'where clause'

Adding the LATERAL keyword makes the query legal:添加LATERAL关键字使查询合法:

SELECTsalesperson.name,max_sale.amount,max_sale.customer_name
FROMsalesperson,-- find maximum size and customer at same timeLATERAL(SELECT amount, customer_nameFROM all_salesWHERE all_sales.salesperson_id = salesperson.idORDER BY amount DESC LIMIT 1)AS max_sale;

In short, LATERAL is the efficient solution to all drawbacks in the two approaches just discussed.

简而言之,LATERAL是上述两种方法中所有缺陷的有效解决方案。

MySQL 8.0-13.2.11.9 Lateral Derived Tables(横向派生表)相关推荐

  1. mysql8.0.13 rpm_Centos7 安装mysql 8.0.13(rpm)的教程详解

    yum or rpm? yum安装方式很方便,但是下载mysql的时候从官网下载,速度较慢. rpm安装方式可以从国内镜像下载mysql的rpm包,比较快.rpm也适合离线安装. 环境说明 •操作系统 ...

  2. LATERAL横向派生表

    参考董旭阳TonyDong的博客,网址:https://blog.csdn.net/horses/article/details/86510905 lateral 横向的 mysql数据库从8.0支持 ...

  3. mysql8.0.13安装版_windows下mysql 8.0.13 解压版安装图文教程

    本文为大家分享了mysql8.0.13安装图文教程,供大家参考,具体内容如下 1.1. 下载: 我下载的是64位系统的zip包: 下载地址 下载zip的包 1.2.配置环境变量: 变量名:MYSQL_ ...

  4. MySQL 8.0.13安装教程(windows 64位)

    1. 先去官网下载点击的MySQL的下载 2.下载完成后解压 配置系统环境变量 去系统的环境变量的path里添加一个mysql的配置  指向mysql的bin目录 3.配置初始化的my.ini文件的文 ...

  5. centos安装mysql8.0.13_CentOS 7.4安装MySql 8.0.13及配置

    https://dev.mysql.com/downloads/mysql/ 官网的社区版的下载地址 最终的下载地址是https://cdn.mysql.com//Downloads/MySQL-8. ...

  6. mysql 8.0.13解压版安装_mysql 8.0.13 解压版安装配置方法图文教程

    一.安装 1.下载mysql 下载地址:链接地址 在浏览器打开网页后,下载如图所示压缩包 下载完成后将该压缩包进行解压,位置自定义,如:D:\Developer\mysql-8.0.13-winx64 ...

  7. linux64位系统需要安装32位mysql_在Ubuntu16.04 Linux 64位环境下安装二进制版本MySQL 8.0.13...

    a.MySQL依赖于libaio库.如果此库不在本地安装,则数据目录初始化和随后的服务器启动步骤将失败.如果需要,请使用适当的包管理器安装它.例如,基于云计算的系统: hell> apt-cac ...

  8. win10下安装绿色版mysql 8.0.13

    下载mysql: MySQL官方网站下载最新的MySQL Community Server版本: https://dev.mysql.com/downloads/mysql/ 我这里为mysql-8. ...

  9. 解决Navicat for MySQL 连接 Mysql 8.0.13出现1251- Client does not support authentication protocol 错误

    问题 1.问题描述 2.解决方案 3.特别注意 1.问题描述 用了navicat来管理Mysql关系型数据库,但是发现新建连接时报错1251,怎么解决呢? 2.解决方案 命令行打开,进入C盘里的mys ...

最新文章

  1. centos6 进入命令行_CentOS 6.x误删libc.so.6,紧急恢复
  2. 大厂面试必问!如何写出高效率的SQL
  3. Spring中IoC创建对象方式(构造器注入)
  4. arraylist插入数据_集合系列 List(二):ArrayList
  5. easyUI 鼠标悬浮 和截取
  6. LINUX下载编译libcurl
  7. Proteus 8.13 安装教程
  8. Linux 命令之 gzip -- 压缩和解压文件
  9. instant-ngp
  10. 【朝花夕拾】Lint使用篇
  11. Android端FMODSoundTouch音频变声解决方案
  12. 使用服务器备份还原Linux系统
  13. 银行利息,活期,定期,本金知识集锦!
  14. 保姆级二进制安装高可用k8s集群文档(1.23.8)
  15. 细菌觅食算法BFOA
  16. 华擎N3150J3160安装ESXi,然后组建家庭网络
  17. 技术VS管理,哪个更重要?
  18. 三态内容寻址存储器(TCAM)概念
  19. mysql log-slave-update_mysql数据库log-slave-updates 参数解释
  20. FlowForge 重要组件及概念

热门文章

  1. 关于GetDlgItem、GetDlgCtrlID
  2. 数据分析可视化04 图表组件:Echarts数据可视化图表基础
  3. Java 反射系列 —— 学习笔记
  4. 计蒜客模拟赛5-礼物盒
  5. 资讯 | 图扑受邀参加第二十三届中国国际高新技术成果交易会
  6. 宠物健康护理员怎么考?宠物健康护理员证书
  7. K8S 证书过期解决办法
  8. uniapp首次进入app弹窗《隐私条款》
  9. java变量三要素_Java零基础快速入门|变量
  10. 基于php+mysql的菜品食谱美食网