最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Mysql樹(shù)形表的2種查詢(xún)解決方案(遞歸與自連接)

 更新時(shí)間:2023年11月25日 08:35:04   作者:懶羊羊.java  
MySQL作為一個(gè)關(guān)系型數(shù)據(jù)庫(kù),存儲(chǔ)著許多的數(shù)據(jù)信息,在實(shí)際應(yīng)用中經(jīng)常會(huì)遇到需要存儲(chǔ)樹(shù)形結(jié)構(gòu)數(shù)據(jù)的情境,例如部門(mén)結(jié)構(gòu)、商品分類(lèi)等,這篇文章主要給大家介紹了關(guān)于Mysql樹(shù)形表的2種查詢(xún)解決方案,分別是遞歸與自連接,需要的朋友可以參考下

你有沒(méi)有遇到過(guò)這樣一種情況:

一張表就實(shí)現(xiàn)了一對(duì)多的關(guān)系,并且表中每一行數(shù)據(jù)都存在“爺爺-父親-兒子-…”的聯(lián)系,這也就是所謂的樹(shù)形結(jié)構(gòu)

對(duì)于這樣的表很顯然想要通過(guò)查詢(xún)來(lái)實(shí)現(xiàn)價(jià)值絕對(duì)是不能只靠select * from table 來(lái)實(shí)現(xiàn)的,下面提供兩種解決方案:

1.自連接

inner join 關(guān)鍵可以實(shí)現(xiàn)多種分類(lèi)的查詢(xún),其實(shí)SQL很簡(jiǎn)單

SELECT
	one.id one_id,
	one.label one_label,
	two.id two_id,
	two.label two_label
FROM
	course_category one
	INNER JOIN course_category two ON two.parentid=one.id
	INNER JOIN course_category three ON three.parentid=two.id
	WHERE one.id='1' AND one.is_show='1' AND two.is_show='1'
	ORDER BY one.orderby,two.orderby

也是規(guī)規(guī)矩矩的就查出一整棵樹(shù)

這種查詢(xún)的原則就是通過(guò)parentId去實(shí)現(xiàn),“爺爺找爸爸,爸爸找兒子,兒子找孫子”,下面來(lái)逐幀慢放:

1.one

2.one,two

3.one,two,three

可以看到,只有在樹(shù)的層級(jí)確定的情況下我才能選擇性的去自連接子表,某種意義上來(lái)講這種方法存在弊端,我要是insert進(jìn)去層級(jí)更低的新子節(jié)點(diǎn)那我的sql就得改變,從而就造成了一個(gè)“動(dòng)一發(fā)而牽全身”的硬編碼問(wèn)題,實(shí)在是不夠穩(wěn)妥!

2.遞歸!

向上遞歸

首先聲明,如果mysql的版本低于8是不支持遞歸查詢(xún)的函數(shù)的!

下面來(lái)看一下如何用遞歸優(yōu)雅的實(shí)現(xiàn),從樹(shù)根查到樹(shù)頂:

先來(lái)看一個(gè)簡(jiǎn)單的Demo

	with RECURSIVE t1 AS(
		SELECT 1 AS n
		union all
		SELECT n+1 FROM t1 WHERE n<5
	)
	SELECT * from t1

該怎么理解這每一步呢?
 

WITH RECURSIVE t1 AS:

這是遞歸查詢(xún)的開(kāi)始,創(chuàng)建了一個(gè)名為t1的遞歸表。

SELECT 1 AS n:

在t1表中,插入了一個(gè)初始行,值為1,命名為n。

UNION ALL:

使用UNION ALL運(yùn)算符將初始行和遞歸查詢(xún)結(jié)果合并,形成遞歸步驟。這也就是下次遞歸的起點(diǎn)表

SELECT n+1 FROM t1 WHERE n<5:

遞歸部分的查詢(xún),從t1表中選擇n加1的結(jié)果,當(dāng)n小于5時(shí)進(jìn)行遞歸。

SELECT * FROM t1:

最終查詢(xún),返回t1表的所有行。

其實(shí)在使用遞歸的過(guò)程只需要注意要去避免死龜就好!

如何去查開(kāi)頭的那張樹(shù)形表呢?這樣就好:

with recursive temp as (
select * from  course_category p where  id= '1'
 union all
select t.* from course_category t inner join temp on temp.id = t.parentid
)
select *  from temp order by temp.id, temp.orderby

下面我們逐幀分析:

其實(shí)關(guān)鍵的地方就在于第三步,在樹(shù)根的基礎(chǔ)上去找葉子:

神之一手:
select t.* from course_category t inner join temp on temp.id = t.parentid
這就是遞歸相較于第一種方式可以無(wú)視層級(jí)inner jion的關(guān)鍵,因?yàn)檫@個(gè)動(dòng)作已經(jīng)被遞歸自動(dòng)完成了,遞歸巧妙地一點(diǎn)就在這里!

向下遞歸

基于向上遞歸父找子的思想,向下遞歸則是子找父,即在葉子基礎(chǔ)上union all之后去找根

子的parentId=父的id

with recursive temp as (
select * from  course_category p where  id= '1-1-1'
 union all
select t.* from course_category t inner join temp on temp.parentid = t.id  
//temp表是下次遞歸的基礎(chǔ)
)
select *  from temp order by temp.id, temp.orderby

值得注意的是Mysql為了避免無(wú)限遞歸遞歸次數(shù)為1000次,也可以人為來(lái)設(shè)置cte_max_recursion_depth和max_execution_time來(lái)自定義遞歸深度和執(zhí)行時(shí)間

使用遞歸的好處無(wú)需言語(yǔ),一次io連接就搞定了全部

總結(jié)

到此這篇關(guān)于Mysql樹(shù)形表的2種查詢(xún)解決方案的文章就介紹到這了,更多相關(guān)Mysql樹(shù)形表查詢(xún)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • mysql亂碼問(wèn)題分析與解決方法

    mysql亂碼問(wèn)題分析與解決方法

    開(kāi)發(fā)過(guò)程中總避免不了遇到惡心的亂碼,或者由亂碼引發(fā)的一系列問(wèn)題,這里簡(jiǎn)要介紹一下自己遇到的亂碼問(wèn)題和解決問(wèn)題的過(guò)程中的想法以及大致的操作
    2012-11-11
  • MySQL報(bào)錯(cuò)Lost connection to MySQL server during query的解決方案

    MySQL報(bào)錯(cuò)Lost connection to MySQL server&n

    在確保網(wǎng)絡(luò)沒(méi)有問(wèn)題的情況下,服務(wù)器正常運(yùn)行一段時(shí)間后,數(shù)據(jù)庫(kù)拋出了異常"Lost connection to MySQL server during query",本文將給大家介紹MySQL報(bào)錯(cuò)Lost connection to MySQL server during query的解決方案,需要的朋友可以參考下
    2024-01-01
  • 詳解mysql數(shù)據(jù)去重的三種方式

    詳解mysql數(shù)據(jù)去重的三種方式

    本文主要介紹了mysql數(shù)據(jù)去重的三種方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-06-06
  • mysql的docker容器如何設(shè)置默認(rèn)的數(shù)據(jù)庫(kù)技巧詳解

    mysql的docker容器如何設(shè)置默認(rèn)的數(shù)據(jù)庫(kù)技巧詳解

    這篇文章主要為大家介紹了mysql的docker容器如何設(shè)置默認(rèn)的數(shù)據(jù)庫(kù)技巧詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-10-10
  • window10中mysql8.0修改端口port不生效的解決方法

    window10中mysql8.0修改端口port不生效的解決方法

    mysql配置文件默認(rèn)位置,端口號(hào)等信息需要在my.ini文件中修改,若修改安裝位置的my-default文件文件或新建my.ini文件是不生效的,本文主要介紹了window10中mysql8.0修改端口port不生效的解決方法,感興趣的可以了解一下
    2023-11-11
  • MySQL查看日志的實(shí)現(xiàn)

    MySQL查看日志的實(shí)現(xiàn)

    MySQL日志記錄了服務(wù)器的啟動(dòng)和運(yùn)行狀態(tài),包括錯(cuò)誤日志、二進(jìn)制日志、查詢(xún)?nèi)罩竞吐樵?xún)?nèi)罩?這些日志對(duì)于故障排除和性能優(yōu)化至關(guān)重要,下面就來(lái)詳細(xì)的介紹一下
    2026-01-01
  • DBeaver如何將mysql表結(jié)構(gòu)以表格形式導(dǎo)出

    DBeaver如何將mysql表結(jié)構(gòu)以表格形式導(dǎo)出

    DBeaver是一款多功能數(shù)據(jù)庫(kù)工具,支持包括MySQL在內(nèi)的多種數(shù)據(jù)庫(kù),本文介紹如何使用DBeaver將MySQL的表結(jié)構(gòu)以表格形式導(dǎo)出,為數(shù)據(jù)庫(kù)管理和文檔整理提供便利,這種方法簡(jiǎn)潔有效,適合需要文檔化數(shù)據(jù)庫(kù)結(jié)構(gòu)的開(kāi)發(fā)者和數(shù)據(jù)庫(kù)管理員
    2024-10-10
  • 淺談mysql可有類(lèi)似oracle的nvl的函數(shù)

    淺談mysql可有類(lèi)似oracle的nvl的函數(shù)

    下面小編就為大家?guī)?lái)一篇淺談mysql可有類(lèi)似oracle的nvl的函數(shù)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2017-02-02
  • mysql派生表(Derived Table)簡(jiǎn)單用法實(shí)例解析

    mysql派生表(Derived Table)簡(jiǎn)單用法實(shí)例解析

    這篇文章主要介紹了mysql派生表(Derived Table)簡(jiǎn)單用法,結(jié)合實(shí)例形式分析了mysql派生表的原理、簡(jiǎn)單使用方法及操作注意事項(xiàng),需要的朋友可以參考下
    2019-12-12
  • MySQL死鎖原因、檢測(cè)與解決方案(含詳細(xì)圖文)

    MySQL死鎖原因、檢測(cè)與解決方案(含詳細(xì)圖文)

    死鎖是指兩個(gè)或多個(gè)事務(wù)在執(zhí)行過(guò)程中,因爭(zhēng)奪鎖資源而造成的一種相互等待的現(xiàn)象,若無(wú)外力干預(yù),這些事務(wù)將永遠(yuǎn)無(wú)法繼續(xù)執(zhí)行,這篇文章主要介紹了MySQL死鎖原因、檢測(cè)與解決方案的相關(guān)資料,需要的朋友可以參考下
    2026-04-04

最新評(píng)論

道孚县| 海兴县| 汕尾市| 桂东县| 本溪市| 深泽县| 垦利县| 新密市| 封开县| 内黄县| 新巴尔虎右旗| 达拉特旗| 大埔县| 沂南县| 阿拉善左旗| 波密县| 双流县| 洞头县| 环江| 蕉岭县| 巴林左旗| 通河县| 洪湖市| 河间市| 赤壁市| 海晏县| 如东县| 余江县| 安新县| 称多县| 青铜峡市| 白河县| 宿迁市| 保定市| 扶沟县| 丹寨县| 牙克石市| 天津市| 寻乌县| 安溪县| 缙云县|