欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

mysql遞歸函數(shù)with?recursive的用法舉例

 更新時間:2022年08月16日 16:32:14   作者:cyan_orange  
在實際開發(fā)的過程中,我們會遇到一些數(shù)據(jù)是層級關(guān)系的、要展示數(shù)據(jù)子父級關(guān)系的時候,下面這篇文章主要給大家介紹了關(guān)于mysql遞歸函數(shù)with?recursive的用法舉例,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下

AS 用法:

AS在mysql用來給列/表起別名.

有時,列的名稱是一些表達(dá)式,使查詢的輸出很難理解。要給列一個描述性名稱,可以使用列別名。

要給列添加別名,可以使用AS關(guān)鍵詞后跟別名

例子1:

SELECT 
 [column_1 | expression] AS col_name
FROM table_name;

如果別名包含空格,則必須引用以下內(nèi)容:

例子2:

SELECT 
 [column_1 | expression] AS 'col name'
FROM table_name;

with(Common Table Expressions/CTE)用法:

with在mysql中被稱為公共表達(dá)式,可以作為一個臨時表然后在其他結(jié)構(gòu)中調(diào)用.如果是自身調(diào)用那么就是后面講的遞歸.

語法:

with_clause:
    WITH [RECURSIVE]
        cte_name [(col_name [, col_name] ...)] AS (subquery)
        [, cte_name [(col_name [, col_name] ...)] AS (subquery)] ...

cte_name :公共表達(dá)式的名稱,可以理解為表名,用來表示as后面跟著的子查詢

col_name :公共表達(dá)式包含的列名,可以寫也可以不寫

例子1:

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;

例子2:

WITH cte (col1, col2) AS
(
  SELECT 1, 2
  UNION ALL
  SELECT 3, 4
)
SELECT col1, col2 FROM cte;

例子3:

這里的第一個as后面接的是子查詢,第二個as表示列名,而不是子查詢.

WITH cte AS
(
  SELECT 1 AS col1, 2 AS col2
  UNION ALL
  SELECT 3, 4
)
SELECT col1, col2 FROM cte;

with的合法用法:

在子查詢(包括派生的表子查詢)的開始處

SELECT ... WHERE id IN (WITH ... SELECT ...) ...
SELECT * FROM (WITH ... SELECT ...) AS dt ...

同一級別只允許一個WITH子句。同一級別的WITH后面跟著WITH是不允許的,下面是非法用法:

WITH cte1 AS (...) WITH cte2 AS (...) SELECT ...

改為合法用法:

WITH cte1 AS (SELECT 1)
SELECT * FROM (WITH cte2 AS (SELECT 2) SELECT * FROM cte2 JOIN cte1) AS dt;

在這里面as代表列名,sql不是順序執(zhí)行的,這一點了解的話就很好理解這個as了

簡單遞歸用法:

首先我們引出一個問題: 什么叫做遞歸?

遞歸:給定函數(shù)初始條件,然后反復(fù)調(diào)用自身直到終止條件.

例子1:遞歸得到依次遞增的序列:

WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte WHERE n < 5
)
SELECT * FROM cte;

運行結(jié)果:

+------+
| n    |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
+------+

官方文檔中對于這個寫法的解釋:

At each iteration, that SELECT produces a row with a new value one greater than the value of n from the previous row set. The first iteration operates on the initial row set (1) and produces 1+1=2; the second iteration operates on the first iteration’s row set (2) and produces 2+1=3; and so forth. This continues until recursion ends, which occurs when n is no longer less than 5.

用python實現(xiàn)就是:

def cte(n):
	print(n)
	if n<5:
		cte(n+1)

也就是說,一個with recursive 由兩部分組成.第一部分是非遞歸部分(union all上方),第二部分是遞歸部分(union all下方).遞歸部分第一次進(jìn)入的時候使用非遞歸部分傳遞過來的參數(shù),也就是第一行的數(shù)據(jù)值,進(jìn)而得到第二行數(shù)據(jù)值.然后根據(jù)第二行數(shù)據(jù)值得到第三行數(shù)據(jù)值.

例子2:遞歸得到不斷復(fù)制的字符串

這里的as表示列名,表示說這個CTE有兩個列,也可以寫為with cte(n,str) as (subquery)

WITH RECURSIVE cte AS
(
  SELECT 1 AS n, 'abc' AS str
  UNION ALL
  SELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
)
SELECT * FROM cte;

結(jié)果:

+------+------+
| n    | str  |
+------+------+
|    1 | abc  |
|    2 | abc  |
|    3 | abc  |
+------+------+

這里的話concat是每一次都連接一個str,這個str來自上一行的結(jié)果,但是最終輸出卻是每一行都沒有變化的值,這是為什么?
這是因為我們在聲明str的時候限制了它的字符長度,使用 類型轉(zhuǎn)換CAST(‘abc’ AS CHAR(30)) 就可以得到復(fù)制的字符串了.
**注意:**這里也可能會報錯,看mysql模式.在嚴(yán)格模式下這里會顯示Error Code: 1406. Data too long for column 'str' at row 1

關(guān)于strict SQL mode和nonstrict SQL mode:mysql 嚴(yán)格模式 Strict Mode說明

WITH RECURSIVE cte AS
(
  SELECT 1 AS n, CAST('abc' AS CHAR(20)) AS str
  UNION ALL
  SELECT n + 1, CONCAT(str, str) FROM cte WHERE n < 3
)
SELECT * FROM cte;

+------+--------------+
| n    | str          |
+------+--------------+
|    1 | abc          |
|    2 | abcabc       |
|    3 | abcabcabcabc |
+------+--------------+

當(dāng)然,如果上一行的值有多個,我們還可以對多個值進(jìn)行重新組合得到我們想要的結(jié)果,比如下面這個例子.

例子3:生成斐波那契數(shù)列

WITH RECURSIVE fibonacci (n, fib_n, next_fib_n) AS
(
  SELECT 1, 0, 1
  UNION ALL
  SELECT n + 1, next_fib_n, fib_n + next_fib_n
    FROM fibonacci WHERE n < 10
)
SELECT * FROM fibonacci;

結(jié)果:

+------+-------+------------+
| n    | fib_n | next_fib_n |
+------+-------+------------+
|    1 |     0 |          1 |
|    2 |     1 |          1 |
|    3 |     1 |          2 |
|    4 |     2 |          3 |
|    5 |     3 |          5 |
|    6 |     5 |          8 |
|    7 |     8 |         13 |
|    8 |    13 |         21 |
|    9 |    21 |         34 |
|   10 |    34 |         55 |
+------+-------+------------+

語法說明:

UNION ALL與UNION DISTINCT UNION ALL:

  • UNION ALL:
    非遞歸部分和遞歸部分用UNION ALL分隔,那么所有的行都會被加入到最后的表中
  • UNION DISTINCT:
    非遞歸部分和遞歸部分用UNION DISTINCT分隔,重復(fù)的行被消除。這對于執(zhí)行傳遞閉包的查詢非常有用,以避免無限循環(huán)。

limit控制遞歸次數(shù)

recursive(第二個select)不能使用的結(jié)構(gòu):

官網(wǎng)的描述:

The recursive SELECT part must not contain these constructs:

Aggregate functions such as SUM()

Window functions

GROUP BY

ORDER BY

DISTINCT

限制遞歸次數(shù)/時間:

當(dāng)出現(xiàn)不符合設(shè)置情況的會報錯,分為以下幾種設(shè)置方法:

  • cte_max_recursion_depth :default 設(shè)置為1000,表達(dá)遞歸的層數(shù).可以使用如下語句修改這個值:
SET SESSION cte_max_recursion_depth = 10;      -- permit only shallow recursion
SET SESSION cte_max_recursion_depth = 1000000; -- permit deeper recursion

當(dāng)然也可以設(shè)置為global,也就是set global cte_max_recursion_depth = 1000000;這樣子就對全局的遞歸都有限制

  • max_execution_time :設(shè)置最近的遞歸時間
SET max_execution_time = 1000; -- impose one second timeout
  • MAX_EXECUTION_TIME:設(shè)置全局的遞歸時間

官網(wǎng)文檔說明如下:

  • The cte_max_recursion_depth system variable enforces a limit on the
    number of recursion levels for CTEs. The server terminates execution
    of any CTE that recurses more levels than the value of this variable.
  • The max_execution_time system variable enforces an execution timeout
    for SELECT statements executed within the current session.
  • The MAX_EXECUTION_TIME optimizer hint enforces a per-query execution
    timeout for the SELECT statement in which it appears.
  • limit:限之最大行的數(shù)量
WITH RECURSIVE cte (n) AS
(
  SELECT 1
  UNION ALL
  SELECT n + 1 FROM cte LIMIT 10000
)
SELECT * FROM cte;

補(bǔ)充:MySql8使用WITH RECURSIVE進(jìn)行遞歸查詢下級節(jié)點數(shù)據(jù)

#查詢id=62的所有子節(jié)點
WITH RECURSIVE temp AS (
		SELECT * FROM tbsys_office o WHERE o.id=62
		UNION ALL
		SELECT o.* FROM tbsys_office o,temp t WHERE t.id=o.parent_id
) SELECT * FROM temp;
#查詢id=80的所有父節(jié)點
WITH RECURSIVE temp AS (
		SELECT * FROM tbsys_office o WHERE o.id=80
		UNION ALL
		SELECT o.* FROM tbsys_office o,temp t WHERE t.parent_id=o.id
) SELECT * FROM temp;

總結(jié)

到此這篇關(guān)于mysql遞歸函數(shù)with recursive用法的文章就介紹到這了,更多相關(guān)mysql遞歸函數(shù)with recursive內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • MYSQL關(guān)聯(lián)關(guān)系查詢方式

    MYSQL關(guān)聯(lián)關(guān)系查詢方式

    文章詳細(xì)介紹了MySQL中如何使用內(nèi)連接和左外連接進(jìn)行表的關(guān)聯(lián)查詢,并展示了如何選擇列和使用別名,文章還提供了一些關(guān)于查詢優(yōu)化的建議,并鼓勵讀者參考和支持腳本之家
    2025-02-02
  • mysql?8.0.26?安裝配置方法圖文教程

    mysql?8.0.26?安裝配置方法圖文教程

    這篇文章主要為大家詳細(xì)介紹了mysql?8.0.26?安裝配置方法圖文教程,文中安裝步驟介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • mysql5.7.13 環(huán)境搭建教程(解壓縮版)

    mysql5.7.13 環(huán)境搭建教程(解壓縮版)

    這篇文章主要為大家詳細(xì)介紹了mysql解壓縮版環(huán)境搭建教程,具有一定的實用性,感興趣的小伙伴們可以參考一下
    2016-07-07
  • MySql如何查看索引并實現(xiàn)優(yōu)化

    MySql如何查看索引并實現(xiàn)優(yōu)化

    這篇文章主要介紹了MySql如何查看索引并實現(xiàn)優(yōu)化,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2020-12-12
  • 徹底搞懂MySQL存儲過程和函數(shù)

    徹底搞懂MySQL存儲過程和函數(shù)

    我們大家都知道MySQL 存儲過程是從 MySQL 5.0 開始逐漸增加新的功能,下面這篇文章主要給大家介紹了關(guān)于MySQL存儲過程和函數(shù)的相關(guān)資料,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-04-04
  • mysql的udf編程之非阻塞超時重傳

    mysql的udf編程之非阻塞超時重傳

    這篇文章主要介紹了mysql udf編程的非阻塞超時重傳示例,需要的朋友可以參考下
    2014-03-03
  • MySQL對window函數(shù)執(zhí)行sum函數(shù)可能出現(xiàn)的一個Bug

    MySQL對window函數(shù)執(zhí)行sum函數(shù)可能出現(xiàn)的一個Bug

    這篇文章主要給大家介紹了關(guān)于MySQL對window函數(shù)執(zhí)行sum函數(shù)可能出現(xiàn)的一個Bug,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者使用MySQL具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Centos中徹底刪除Mysql(rpm、yum安裝的情況)

    Centos中徹底刪除Mysql(rpm、yum安裝的情況)

    這篇文章主要介紹了Centos中徹底刪除Mysql(rpm、yum安裝的情況),本文直接給出操作代碼,需要的朋友可以參考下
    2015-02-02
  • MySql數(shù)據(jù)庫之a(chǎn)lter表的SQL語句集合

    MySql數(shù)據(jù)庫之a(chǎn)lter表的SQL語句集合

    mysql之a(chǎn)lter表的SQL語句集合,包括增加、修改、刪除字段,重命名表,添加、刪除主鍵等。本文給大家介紹MySql數(shù)據(jù)庫之a(chǎn)lter表的SQL語句集合,感興趣的朋友一起學(xué)習(xí)吧
    2016-04-04
  • MySQL實現(xiàn)去重的幾種方法小結(jié)

    MySQL實現(xiàn)去重的幾種方法小結(jié)

    在MySQL中,SELECT DISTINCT 和 GROUP BY 可以用來去除重復(fù)記錄,二者有相似的功能,但在某些情況下有所不同,本文將通過代碼示例給大家詳細(xì)介紹這幾種方法,感興趣的小伙伴跟著小編一起來看看吧
    2024-07-07

最新評論