以下文章來源于MySQL解決方案工程師 你画,作者徐軼韜
Common table expression (CTE)通用表表達式是MySQL8推出的新功能皆刺。它是一種臨時表垂寥,使用“WITH”命令,可以執(zhí)行遞歸查詢膀篮。
先看一下如何使用WITH語句:
WITH
cte1 AS (SELECT a, b FROM table1),
cte2 AS (SELECT c, d FROM table2)
SELECT b, d FROM cte1 JOIN cte2
WHERE cte1.a= cte2.c;
看起來是不是像是將派生表放在了前面?是的岂膳,使用WITH語句誓竿,可以使你的查詢看起來清晰明了,更加易讀谈截,但好處不止是這個筷屡,CTE可以多次參照。例如:
WITH d AS(SELECT a, b, SUM(c) s FROM t1 GROUP BY a, b)
SELECT ... FROM d AS d1 JOIN d AS d2 ON d1.b = d2.a;
也可以在其他CTE中引用CTE名稱簸喂,從而使CTE能夠基于其他CTE進行定義毙死。例如:
WITH d1 AS(SELECT … FROM …),
d2 AS (SELECT … FROM d1 …)
SELECT
FROM d1, d2 …
此外,CTE可以引用自身來定義遞歸CTE喻鳄。遞歸CTE常見于生成序列扼倘,層次或樹狀結(jié)構(gòu)的遍歷。例如:
打印1到10:
WITHRECURSIVE qn AS
( SELECT 1 AS a
UNION ALL
SELECT 1+a FROM qn WHERE a<10
)
SELECT *FROM qn;
插入1到10:
INSERT INTOnumbers
WITHRECURSIVE qn AS
( SELECT 1 AS a
UNION ALL
SELECT 1+a FROM qn WHERE a<10
)
SELECT *FROM qn;
層次遍歷:
CREATE TABLEemployees (
id INT PRIMARY KEY,
name VARCHAR(100),
manager_id INT,
FOREIGN KEY (manager_id) REFERENCES employees(id) );
借用一下“蜀國”的人物充當一下員工
INSERT INTOemployees VALUES
(333, "劉備", NULL), #
(198, "關(guān)羽", 333), #
(692, "張飛", 333),
(29, "兵甲", 198),
(4610,"兵乙", 29),
(72, "兵丁", 29),
(123, "兵己", 692);
執(zhí)行一下查詢:
WITHRECURSIVE
emp_ext (id,name, path) AS (
SELECT id, name, CAST(id AS CHAR(200))
FROM employees
WHERE manager_id IS NULL
UNION ALL
SELECT s.id, s.name,
CONCAT(m.path, ",", s.id)
FROM emp_ext m JOIN employees s
ON m.id=s.manager_id )
SELECT * FROM emp_ext ORDER BY path;
結(jié)果如下:
使用CTE除呵,除了上述的好處之外再菊,還會帶來性能的提升。原因在于颜曾,如果使用派生表進行多次參照纠拔,將會多次物化相同的表。更多的空間泛豪,更多的時間稠诲,更長的鎖等等會引起性能問題,類似于視圖引用诡曙。而CTE不論使用了幾次參照臀叙,僅物化一次。
有關(guān)CTE的使用就介紹到這里价卤,關(guān)于CTE的更多細節(jié)劝萤,請參照官網(wǎng)手冊:https://dev.mysql.com/doc/refman/8.0/en/with.html
希望能為從事開發(fā)工作的您帶來幫助。
感謝您關(guān)注MySQL荠雕!