日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

mysql 递归查找父节点_MYSQL递归查询,根据子类ID查询所有父类(最全)

發布時間:2023/12/19 数据库 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 mysql 递归查找父节点_MYSQL递归查询,根据子类ID查询所有父类(最全) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

數據表結構

id??? name? parent_id

1??????? A??????? 0

2??????? B??????? 1

3??????? C??????? 1

4??????? D??????? 2

5??????? E??????? 4

6??????? F??????? 1

7??????? G??????? 1

注:parent_id 為0表示頂級父節點,即A是頂級父輩,沒有父節點

轉儲SQL表結構及數據

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------

-- Table structure for demo

-- ----------------------------

DROP TABLE IF EXISTS `demo`;

CREATE TABLE `demo` (

`id` int(11) NOT NULL AUTO_INCREMENT,

`name` varchar(255) NOT NULL,

`parent_id` int(11) NOT NULL,

PRIMARY KEY (`id`)

) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

-- ----------------------------

-- Records of demo

-- ----------------------------

INSERT INTO `demo` VALUES ('1', 'A', '0');

INSERT INTO `demo` VALUES ('2', 'B', '1');

INSERT INTO `demo` VALUES ('3', 'C', '1');

INSERT INTO `demo` VALUES ('4', 'D', '2');

INSERT INTO `demo` VALUES ('5', 'E', '4');

INSERT INTO `demo` VALUES ('6', 'F', '1');

INSERT INTO `demo` VALUES ('7', 'G', '1');

需求:根據一個子ID,查詢所有父類

SQL如下:

SELECT T2.id, T2.name

FROM (

SELECT

@r AS _id,

(SELECT @r := parent_id FROM demo WHERE id = _id) AS parent_id,

@l := @l + 1 AS lvl

FROM

(SELECT @r := 5, @l := 0) vars,

demo h

WHERE @r <> 0) T1

JOIN demo T2

ON T1._id = T2.id

ORDER BY T1.lvl DESC結果如下

id? ? ? name

1? ? ? ? ?A

2? ? ? ? ?B

4? ? ? ? ?D

5? ? ? ? ?E

分析過程(答疑過程)

我使用將SQL語句拆分的方式,并展示每句SQL運行結果,讓各位可以看的更明白,以便于根據你自己的業務需求進行更改

1、先不管T2,先把T1的SQL抽出來看

SELECT

@r AS _id,

(SELECT @r := parent_id FROM demo WHERE id = _id) AS parent_id,

@l := @l + 1 AS lvl

FROM

(SELECT @r := 5, @l := 0) vars,

demo h

WHERE @r <> 0

運行結果

從這里可以看出,其實T1已經找出ID為5節點的所有父節點了,和T2(即demo表)進行左連接,只不過是為了根據Id獲取Name而已。而且還可以看出@l其實在整個SQL中并沒有什么作用,只是用來標識節點的等級,底級子節點的lvl為1,父節點lvl值越大表示越靠近頂級父節點,想象一下樹結構,你就明白了

2、搞明白@r := 5

SELECT @r := 5, @l := 0

運行結果

這里看出,其實@r,@l 就是一個變量而已,

作為變量自然你可以隨便起名,當然也可以隨便賦值,改成@a,@b也都是可以的

那這句SQL的意思就出來了,它表示給變量@r賦值,值為5,給@l賦值,值為0

因此,其實整個SQL的意思也明了了就是根據子ID5,查詢所有父類

3、搞懂變量@r 值如何變化

@r AS _id,

(SELECT @r := parent_id FROM demo WHERE id = _id) AS parent_id

根據MYSQL執行順序(在文章末尾處),SQL語句在執行時會先執行From,即會先執行上一步的賦值操作,因此這里的_id值為5,所以上面的SQL等同于如下SQL

SELECT @r := parent_id FROM demo WHERE id = 5

運行結果

這句SQL肯定沒人不會,但是有一個點很重要,它是整個執行過程的核心,就是@r := parent_id,它在查詢Id為5的節點的父Id時,把這個父Id同時賦給了變量@r。因此@r值改變了,它從5變為了4。

這個時候思路就很清晰了,只要我們設置限制條件,讓SQL在@r為0的時候結束循環就OK了

4、<>符號的含義

WHERE @r <> 0

這個就沒什么好說的了,<>符號在MYSQL中表示不等于,這就是我們在第四步中所說的限制條件,它限制了@r這個變量不能等于0。所以當@r不等于0時,SQL語句會根據子ID向上查詢父ID,又把父ID當做子ID賦值給@r,再次向上查詢,直至@r變量的值為0為止。

補充:如果業務不需要,可以完全可以去掉@l變量

SELECT ,

@a AS _id,

(SELECT @a := parent_id FROM demo WHERE id = _id) AS parent_id

FROM

(SELECT @a := 5) vars,

demo h

WHERE @a <> 0

運行結果

可以看出@l其實在整個SQL中并沒有什么作用,只是用來標識節點的等級,這也證實了我們上述第一步的關于@l的解釋

因為這個過程很類似于JAVA通過構造樹結構向上遞歸查詢的方式,所以這個SQL形式被很多人叫做MYSQL遞歸查詢

文章結尾

關于MYSQL的查詢順序

FROM

ON

JOIN

WHERE

GROUP By

CUBE|ROllUP

HAVING

SELECT

DISTINCT

ORDER BY

LIMIT

最先執行的是FROM操作,最后執行的是LIMIT操作。每個操作都會產生一個虛擬表,該虛擬表作為一個處理的輸入

總結

以上是生活随笔為你收集整理的mysql 递归查找父节点_MYSQL递归查询,根据子类ID查询所有父类(最全)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。