WITH在MYSQL中的用法示例詳解
WITH 子句(也稱為公共表表達(dá)式,Common Table Expression,簡稱 CTE)是 SQL 中一種強(qiáng)大的查詢構(gòu)建工具,它可以顯著提高復(fù)雜查詢的可讀性和可維護(hù)性。
一、基本語法結(jié)構(gòu)
WITH cte_name AS ( SELECT ... -- 定義CTE的查詢 ) SELECT ... FROM cte_name; -- 主查詢使用CTE
二、CTE 的核心特點(diǎn)
- 臨時(shí)結(jié)果集:CTE 只在當(dāng)前查詢執(zhí)行期間存在
- 可引用性:定義后可在主查詢中多次引用
- 作用域限制:僅在緊隨其后的單個(gè)語句中有效
三、MySQL 中 CTE 的具體用法
1. 基本 CTE(單表表達(dá)式)
WITH sales_summary AS ( SELECT product_id, SUM(quantity) AS total_sold FROM orders GROUP BY product_id ) SELECT p.product_name, s.total_sold FROM products p JOIN sales_summary s ON p.product_id = s.product_id;
2. 多 CTE 定義(逗號分隔)
WITH customer_orders AS ( SELECT customer_id, COUNT(*) AS order_count FROM orders GROUP BY customer_id ), high_value_customers AS ( SELECT customer_id FROM customer_orders WHERE order_count > 5 ) SELECT c.customer_name FROM customers c JOIN high_value_customers h ON c.customer_id = h.customer_id;
3. 遞歸 CTE(MySQL 8.0+ 支持)
遞歸 CTE 用于處理層次結(jié)構(gòu)數(shù)據(jù):
WITH RECURSIVE org_hierarchy AS ( -- 基礎(chǔ)查詢(錨成員) SELECT id, name, parent_id, 1 AS level FROM organization WHERE parent_id IS NULL UNION ALL -- 遞歸查詢(遞歸成員) SELECT o.id, o.name, o.parent_id, h.level + 1 FROM organization o JOIN org_hierarchy h ON o.parent_id = h.id ) SELECT * FROM org_hierarchy;
四、CTE 的優(yōu)勢
提高可讀性:
- 將復(fù)雜查詢分解為邏輯塊
- 類似編程中的變量定義
避免重復(fù)子查詢:
-- 不使用CTE(重復(fù)子查詢) SELECT * FROM (SELECT ... FROM table1) AS t1 JOIN (SELECT ... FROM table1) AS t2... -- 使用CTE(避免重復(fù)) WITH t1 AS (SELECT ... FROM table1) SELECT * FROM t1 JOIN t1 AS t2...
支持遞歸查詢:處理樹形/層次結(jié)構(gòu)數(shù)據(jù)
五、CTE 與臨時(shí)表的區(qū)別
特性 | CTE | 臨時(shí)表 |
---|---|---|
生命周期 | 僅當(dāng)前語句有效 | 會(huì)話結(jié)束前有效 |
存儲 | 不物理存儲 | 可能存儲在內(nèi)存或磁盤 |
索引 | 不能創(chuàng)建索引 | 可以創(chuàng)建索引 |
可見性 | 僅定義它的查詢可見 | 同一會(huì)話的后續(xù)查詢可見 |
性能 | 優(yōu)化器可能內(nèi)聯(lián)展開 | 需要實(shí)際創(chuàng)建和填充 |
六、實(shí)際應(yīng)用場景
1. 復(fù)雜報(bào)表查詢
WITH monthly_sales AS (...), product_ranking AS (...) SELECT ... FROM monthly_sales JOIN product_ranking...
2. 數(shù)據(jù)清洗管道
WITH raw_data AS (...), cleaned_data AS (...), enriched_data AS (...) SELECT * FROM enriched_data;
3. 層次結(jié)構(gòu)遍歷(組織架構(gòu)、評論線程等)
WITH RECURSIVE comment_tree AS (...) SELECT * FROM comment_tree;
七、性能注意事項(xiàng)
物化提示:
WITH cte_name AS ( SELECT /*+ MATERIALIZE */ ... -- 強(qiáng)制物化 )
合并提示:
WITH cte_name AS ( SELECT /*+ MERGE */ ... -- 強(qiáng)制合并到主查詢 )
遞歸深度控制(MySQL 默認(rèn) 1000):
SET @@cte_max_recursion_depth = 2000;
八、版本兼容性
- MySQL 8.0+ 完整支持 CTE 和遞歸 CTE
- MySQL 5.7 及更早版本不支持 CTE
WITH 子句是現(xiàn)代 SQL 開發(fā)中不可或缺的工具,合理使用可以大幅提升查詢的清晰度和維護(hù)性,特別是在處理多層嵌套或遞歸數(shù)據(jù)時(shí)。
到此這篇關(guān)于WITH在MYSQL中的用法示例詳解的文章就介紹到這了,更多相關(guān)mysql with用法內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
mysql 獲取規(guī)定時(shí)間段內(nèi)的統(tǒng)計(jì)數(shù)據(jù)
這篇文章主要介紹了mysql 獲取規(guī)定時(shí)間段內(nèi)的統(tǒng)計(jì)數(shù)據(jù)的相關(guān)資料,需要的朋友可以參考下2017-05-05MySQL curdate()函數(shù)的實(shí)例詳解
這篇文章主要介紹了MySQL curdate()函數(shù)的實(shí)例詳解的相關(guān)資料,希望通過本文能幫助到大家理解應(yīng)用MysqL curdate()的使用方法,需要的朋友可以參考下2017-09-09深入解析Linux下MySQL數(shù)據(jù)庫的備份與還原
以下是對Linux下MySQL數(shù)據(jù)庫的備份與還原進(jìn)行了詳細(xì)的分析介紹。需要的朋友可以過來參考下2013-08-08mysql常用函數(shù)之group_concat()、group by、count()、case whe
本文主要介紹了mysql常用函數(shù)之group_concat()、group by、count()、case when then的使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-01-01Advanced Pagination for MySQL(mysql高級分頁)
看到葉金榮的一篇關(guān)于mysql分頁的文章,結(jié)合雅虎之前發(fā)的一篇PDF 談?wù)勛约旱目捶?/div> 2016-08-08mysql實(shí)現(xiàn)表內(nèi)增加一個(gè)字段并賦值
這篇文章主要介紹了mysql實(shí)現(xiàn)表內(nèi)增加一個(gè)字段并賦值,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09MySQL臟讀幻讀不可重復(fù)讀及事務(wù)的隔離級別和MVCC、LBCC實(shí)現(xiàn)
這篇文章主要介紹了MySQL臟讀幻讀不可重復(fù)讀及事務(wù)的隔離級別和MVCC、LBCC實(shí)現(xiàn),事務(wù)A?按照查詢條件讀取某個(gè)范圍的記錄,其他事務(wù)又在該范圍內(nèi)出入了滿足條件的新記錄,當(dāng)事務(wù)A再次讀取數(shù)據(jù)到時(shí)候我們發(fā)現(xiàn)多了滿足記錄的條數(shù)2022-07-07最新評論