📅  最后修改于: 2020-11-19 00:48:23             🧑  作者: Mango
在MySQL中,每个语句或查询都会产生一个临时结果或关系。通用表表达式或CTE用于命名该特定语句的执行范围内存在的那些临时结果集,例如CREATE,INSERT,SELECT,UPDATE,DELETE等。
与CTE相关的一些关键点是:
MySQL CTE的语法包括名称,可选列列表以及定义公用表表达式(CTE)的语句/查询。定义CTE之后,我们可以将其用作SELECT,INSERT,UPDATE和DELETE查询中的视图。
以下是MySQL中CTE的基本语法:
WITH cte_name (column_names) AS (query)
SELECT * FROM cte_name;
这是为了确保CTE参数中的列数必须与查询中的列数相同。如果我们尚未在CTE参数中定义列,它将使用定义CTE的查询列。
与派生表类似,它不能存储为对象,并且在执行完查询后将立即丢失。与派生表相比,CTE提供了更好的可读性,并且还提高了性能。
与派生表不同,CTE是可以使用自己的名称进行自我引用的子查询。它也称为递归CTE,也可以在同一查询中多次引用。
与递归CTE相关的一些要点是:
以下是MySQL中递归CTE的基本语法:
WITH RECURSIVE cte_name (column_names) AS ( subquery )
SELECT * FROM cte_name;
在这里,子查询是一个MySQL查询,它使用cte_name作为自己的名称进行引用。
让我们使用各种示例来了解CTE在MySQL中的工作方式。在这里,我们将使用表“ employees”进行演示。假设此表包含以下数据:
执行以下语句以了解CTE的概念。在此示例中,CTE名称是employee_in_california,定义CTE的子查询返回emp_name,emp_age和city这三列。因此,CTE employee_in_california将返回位于加利福尼亚城市的所有雇员。
定义CTE employee_in_california后,我们在SELECT语句中引用了它,以仅选择位于加利福尼亚的那些雇员。
WITH employees_in_california AS (
SELECT * FROM employees WHERE city = 'California'
)
SELECT emp_name, emp_age, city FROM employees_in_california
WHERE emp_age >= 32 ORDER BY emp_name;
执行以上语句后,将给出以下输出。在这里,我们可以看到结果仅返回位于加利福尼亚的员工数据。
更高级的MySQL CTE示例
假设我们有一个名为customer和order的表,其中包含以下数据:
表:客户
表:订单
请参阅以下使用INNER JOIN子句解释高级CTE示例的语句。
WITH total_customer_2020 AS (
SELECT cust_id, name, occupation FROM customer
INNER JOIN orders USING (cust_id)
ORDER BY age
)
SELECT * FROM orders JOIN total_customer_2020 USING (cust_id);
执行后,我们将得到如下输出:
以下示例说明了递归CTE的工作方式。考虑下面的语句,该语句生成一系列的前五个奇数:
WITH RECURSIVE
odd_num_cte (id, n) AS
(
SELECT 1, 1
union all
SELECT id+1, n+2 from odd_num_cte where id < 5
)
SELECT * FROM odd_num_cte;
执行上面的语句后,将给出如下输出:
上面的语句包括两个部分,一个是非递归的,另一个是递归的。
非递归:SELECT 1、1
这部分将产生带有两列的初始行,分别为“ id”和“ n”,以及单行。
递归:从id_ 5的odd_num_cte中选择id + 1,n + 2
这部分负责将行添加到先前的输出,直到不满足终止条件(id <5)。当id达到5时,条件变为假,并且递归过程终止。
MySQL提供了许多上下文来使用WITH子句创建CTE。让我们详细讨论一下。
首先,我们可以在SELECT,UPDATE和DELETE查询的开头使用WITH子句,如下所示。
WITH ... SELECT ...
WITH ... UPDATE ...
WITH ... DELETE ...
其次,我们可以在子查询或派生表子查询的开头使用WITH子句,如下所示:
SELECT ... WHERE id IN (WITH ... SELECT ...);
SELECT * FROM (WITH ... SELECT ...) AS derived_table;
第三,我们可以在包含SELECT子句的SELECT语句的紧前面使用WITH子句,如下所示:
CREATE TABLE ... WITH ... SELECT ...
CREATE VIEW ... WITH ... SELECT ...
INSERT ... WITH ... SELECT ...
REPLACE ... WITH ... SELECT ...
DECLARE CURSOR ... WITH ... SELECT ...
EXPLAIN ... WITH ... SELECT ...