mariadb 10.2/mysql 8.0實現遞歸


查詢1-n的遞歸

mysql> WITH RECURSIVE cte (n) AS
( SELECT 1 /* seed query */
UNION ALL
SELECT n + 1 FROM cte WHERE n < 5 /* recursive query */
)SELECT * FROM cte;
+---+
| n |
+---+
| 1 |
| 2 |
| 3 |
| 4 |
| 5 |
+---+
5 rows in set (0.00 sec)
我們先來看下WITH RECURSIVE子句:

cte是子查詢的名稱,(n)是列,子查詢語句為(SELECT 1 UNION ALL SELECT n+1 FROM cte WHERE n < 5),其中SELECT 1是種子SELECT,只執行一次,而SELECT n+1 FROM cte WHERE n<5是遞歸SELECT,也就是說這個遞歸查詢會一直執行,直到n的值不小於5為止,注意在遞歸SELECT中引用於自身cte。子查詢定義好后,再用一個SELECT來查詢這個cte即可。

借助mysql 8.0的cte(它是iso sql標准的一部分),可以實現遞歸,mariadb 10.2.2開始支持遞歸cte,如下:

+----+----------+--------------+
| ID | ParentID | name         |
+----+----------+--------------+
|  1 |        0 | 河南省       |
|  2 |        1 | 信陽市       |
|  3 |        2 | 淮濱縣       |
|  4 |        3 | 蘆集鄉       |
|  5 |        1 | 安陽市       |
|  6 |        5 | 滑縣         |
|  7 |        6 | 老廟鄉       |
|  8 |        2 | 固始縣       |
|  9 |        8 | 李店鄉       |
| 10 |        2 | 息縣         |
| 11 |       10 | 關店鄉       |
| 12 |        3 | 鄧灣鄉       |
| 13 |        3 | 台頭鄉       |
| 14 |        3 | 谷堆鄉       |
| 15 |        1 | 南陽市       |
| 16 |       15 | 方城縣       |
| 17 |        1 | 駐馬店市     |
| 18 |       17 | 正陽縣       |
+----+----------+--------------+

 由下而上

sql:

with recursive r as 
(
select * from c where id =11 
union all 
select c.* from c,r where c.id=r.ParentID
) select * from r order by id;

 

 result:

+------+----------+-----------+
| ID   | ParentID | name      |
+------+----------+-----------+
|    1 |        0 | 河南省    |
|    2 |        1 | 信陽市    |
|   10 |        2 | 息縣      |
|   11 |       10 | 關店鄉    |
+------+----------+-----------+

由上而下

sql:

with recursive r as
(
select id,name from c where id=1
union all 
select c.id,CONCAT(r.name, '>', c.name) as name from c,r where r.id = c.ParentID
)select id,name from r;

result:

+------+-----------------------------------------+
| id   | name                                    |
+------+-----------------------------------------+
|    1 | 河南省                                  |
|    2 | 河南省>信陽市                           |
|    5 | 河南省>安陽市                           |
|   15 | 河南省>南陽市                           |
|   17 | 河南省>駐馬店市                         |
|    3 | 河南省>信陽市>淮濱縣                    |
|    6 | 河南省>安陽市>滑縣                      |
|    8 | 河南省>信陽市>固始縣                    |
|   10 | 河南省>信陽市>息縣                      |
|   16 | 河南省>南陽市>方城縣                    |
|   18 | 河南省>駐馬店市>正陽縣                  |
|    4 | 河南省>信陽市>淮濱縣>蘆集鄉             |
|    7 | 河南省>安陽市>滑縣>老廟鄉               |
|    9 | 河南省>信陽市>固始縣>李店鄉             |
|   11 | 河南省>信陽市>息縣>關店鄉               |
|   12 | 河南省>信陽市>淮濱縣>鄧灣鄉             |
|   13 | 河南省>信陽市>淮濱縣>台頭鄉             |
|   14 | 河南省>信陽市>淮濱縣>谷堆鄉             |
+------+-----------------------------------------+

完整原理大家可以參考https://mariadb.com/kb/en/library/recursive-common-table-expressions-overview/。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM