mysql?WITH?RECURSIVE語法的具體使用
引言
在 SQL 中,WITH RECURSIVE 是一個用于創(chuàng)建遞歸查詢的語句。它允許你定義一個 Common Table Expression (CTE),該 CTE 可以引用自身的輸出。遞歸 CTE 非常適合于查詢具有層次結(jié)構(gòu)或樹狀結(jié)構(gòu)的數(shù)據(jù),例如組織結(jié)構(gòu)、文件系統(tǒng)或任何其他具有自引用關(guān)系的數(shù)據(jù)。
一、基本語法
WITH RECURSIVE cte_name (column1, column2, ...) AS ( -- 非遞歸的初始部分,定義了 CTE 的起點 SELECT ... FROM ... UNION ALL -- 遞歸部分,可以引用 CTE 的別名 SELECT ... FROM cte_name WHERE ... ) -- 最后的 SELECT 或其他 DML 語句,使用遞歸 CTE SELECT * FROM cte_name;
二、示例
假設(shè)我們有一個表示組織結(jié)構(gòu)的表 employees,其中包含 id, manager_id 和 name 字段。manager_id 是員工的上級經(jīng)理的 id,如果 manager_id 是 NULL,則表示該員工是 CEO 或頂層經(jīng)理。
我們想要查詢整個組織結(jié)構(gòu)中的所有員工及其上級經(jīng)理。
WITH RECURSIVE employee_hierarchy (id, name, manager_id, path) AS ( -- 非遞歸的初始部分:查找頂層經(jīng)理(沒有經(jīng)理的員工) SELECT id, name, manager_id, CONCAT(name, '/') AS path -- 使用 CONCAT 創(chuàng)建初始路徑 FROM employees WHERE manager_id IS NULL UNION ALL -- 遞歸部分:查找所有下屬 SELECT e.id, e.name, e.manager_id, CONCAT(e.name, '/', eh.path) AS path -- 將當(dāng)前員工添加到路徑中 FROM employees e INNER JOIN employee_hierarchy eh ON e.manager_id = eh.id ) SELECT * FROM employee_hierarchy;
在這個例子中:
- WITH RECURSIVE 開始定義一個遞歸 CTE employee_hierarchy。
- CTE 中的 column1, column2, … 是你想要在結(jié)果中選擇的列。
- 初始查詢部分(在 UNION ALL 之前)定義了遞歸的起點,通常是頂級節(jié)點或者查詢的基本情況。
- 遞歸查詢部分(在 UNION ALL 之后)使用 CTE 的別名來引用自身的輸出,以便能夠遞歸地查詢下屬或子節(jié)點。
- UNION ALL 用于合并初始查詢和遞歸查詢的結(jié)果,它允許重復(fù)的行,這是遞歸查詢的關(guān)鍵部分。
- 最后的 SELECT * FROM employee_hierarchy; 是最終的查詢,它將返回 CTE 的全部結(jié)果。
遞歸 CTE 是 SQL 中處理分層數(shù)據(jù)的強大工具,但它們也可能很復(fù)雜,需要仔細設(shè)計以避免無限遞歸或不正確的結(jié)果。
三、實戰(zhàn)案例–查詢 最近12個月的診斷量數(shù)據(jù)
1. 按要求實現(xiàn)以下需求:
1.建表語句如下:
CREATE TABLE rkk_dzblzdl ( id int NOT NULL AUTO_INCREMENT COMMENT ‘id', month varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ‘月份(1-12月)', zdcs int DEFAULT NULL COMMENT ‘診斷次數(shù)', xzqh varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT ‘行政區(qū)劃', PRIMARY KEY (id) )COMMENT=‘電子病歷診斷量';
2.要求查詢 最近12個月的診斷量數(shù)據(jù),按行政區(qū)劃/月份 合并統(tǒng)計;
3.結(jié)果返回 診斷次數(shù),月份,按月份排序;
4.返回 數(shù)據(jù)更新時間,取當(dāng)前最大的月份
2.實現(xiàn)結(jié)果
WITH RECURSIVE RecentMonths AS ( SELECT DATE_FORMAT(CURDATE(), '%Y-%m') AS month UNION ALL SELECT DATE_FORMAT(DATE_SUB(STR_TO_DATE(CONCAT(month, '-01'), '%Y-%m-%d'), INTERVAL 1 MONTH), '%Y-%m') FROM RecentMonths WHERE STR_TO_DATE(CONCAT(month, '-01'), '%Y-%m-%d') > DATE_SUB(CURDATE(), INTERVAL 12 MONTH) ) SELECT COALESCE(r.xzqh, rm.month) AS xzqh, rm.month AS month, SUM(r.zdcs) AS zdcs_count, (SELECT MAX(month) FROM rkk_dzblzdl) AS last_updated_month_in_table FROM RecentMonths rm LEFT JOIN rkk_dzblzdl r ON rm.month = r.month GROUP BY rm.month, r.xzqh ORDER BY STR_TO_DATE(CONCAT(rm.month, '-01'), '%Y-%m-%d') DESC, r.xzqh;
這個查詢使用了遞歸的公用表表達式(CTE)RecentMonths 來生成最近12個月的月份列表。然后,它將這些月份與 rkk_dzblzdl 表進行左連接,以便即使在某個月份沒有診斷數(shù)據(jù)時也能在結(jié)果集中顯示該月份。
COALESCE(r.xzqh, rm.month) 確保即使在某個月份沒有特定行政區(qū)劃的數(shù)據(jù)時,也能顯示月份。
MAX(rm.month) OVER () 是一個窗口函數(shù),用于在整個結(jié)果集上計算最大的月份,并作為 last_updated_month 返回。由于它是窗口函數(shù),所以它的值對于結(jié)果集中的每一行都是相同的。
最后,結(jié)果集按照月份降序和行政區(qū)劃升序進行排序。
到此這篇關(guān)于mysql WITH RECURSIVE語法的具體使用的文章就介紹到這了,更多相關(guān)mysql WITH RECURSIVE內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
MySQL配置文件my.cnf參數(shù)優(yōu)化和中文詳解
這篇文章主要介紹了MySQL配置文件my.cnf參數(shù)優(yōu)化和中文詳解,非常詳細的用中文注釋了各個參數(shù)的作用以及建議值,需要的朋友可以參考下2014-03-03基于mysql實現(xiàn)group by取各分組最新一條數(shù)據(jù)
這篇文章主要介紹了基于mysql實現(xiàn)group by取各分組最新一條數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-09-09Mysql分組查詢每組最新的一條數(shù)據(jù)的五種實現(xiàn)過程
本文介紹了五種在MySQL中獲取每個分組最新一條數(shù)據(jù)的方法,包括子查詢和JOIN、窗口函數(shù)、變量、聚合函數(shù)和子查詢以及使用DISTINCT關(guān)鍵字,推薦使用子查詢和JOIN操作或窗口函數(shù),避免使用變量2024-11-11Mysql日期格式以及內(nèi)置日期函數(shù)用法詳解
MySQL中有多種數(shù)據(jù)類型可以用于日期和時間的表示,這篇文章主要給大家介紹了關(guān)于Mysql日期格式以及內(nèi)置日期函數(shù)用法的相關(guān)資料,文中通過實例代碼介紹的非常詳細,需要的朋友可以參考下2023-05-05MySQL如何更改數(shù)據(jù)庫數(shù)據(jù)存儲目錄詳解
這篇文章主要給大家介紹了關(guān)于MySQL如何更改數(shù)據(jù)庫數(shù)據(jù)存儲目錄的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2018-11-11自用mysql自帶命令實現(xiàn)數(shù)據(jù)庫備份還原的方法
本文章介紹了都是mysql常用的命令一些數(shù)據(jù)導(dǎo)入導(dǎo)出的命令了,只要我們撐握這些命令就可以方法快速的給我們的數(shù)據(jù)庫進行備份還原了2012-04-04