在關係型數據庫中,常常會設計一種上級下級關係數據,即數據中保存這上級的ID。以下所示:html
a |-b |-c |-d |-e |-f |-g
數據庫通常設計爲id和superior_id(父級id)的設計方式,舉例以下,數據中的結構數據以下所示:sql
id superior_id 57adca6415a414043183326f null 57adcbb915a4140431833277 57adca6415a414043183326f test1 57adcbb915a4140431833277 test2 test1 test3 57adcbb915a4140431833277 test4 test3 test5 test5
此時的層級關係爲:數據庫
57adca6415a414043183326f |- 57adcbb915a4140431833277 |- test1 |- test2 |- test3 |- test4 |- test5
--------------------------------------------------------數據準備完畢------------------------------------------------------------數據庫設計
如今產生業務需求,需求爲:查詢對應id下3層之內的全部數據。函數
根據需求,準備查詢方案:測試
1. SQL遞歸查詢(純SQL查詢語句).net
2. 存儲過程或函數設計
3. 代碼基本操做code
4. 初期數據庫設計時準備相應冗餘數據或者準備一數據字段爲:id1-id2-id3-id4.....htm
其中方案3爲最簡單,也是最能跨數據庫操做;方案4須要改變數據庫結構,對於已經存在數據的系統中並不適用,並且若是層級過深數據過長,容易產生其餘問題,此處便再也不介紹這兩種方案。然後方案2中存儲過程對數據庫依賴較大,且改動上較麻煩,須要經過存儲操做的童鞋請參考 http://www.cnblogs.com/interdrp/p/3978018.html。
對於方案1來講,若是使用的是MSSQL,則很是簡單,使用 WITH AS 語法便可,如:
with 臨時表名 as ( select * from 表名 t1 -- 初始數據 UNION all select d.* from 臨時表名 INNER JOIN 表名 d ON d.id = 臨時表名.parentid where ... ) select * from 臨時表名 where ...
可是MySQL中,並無WITH AS 語句,對於當前的業務,暫時的解決方案以下:
SELECT id FROM 表名 t1 WHERE t1.superior_id = '57adca6415a414043183326f' UNION ALL SELECT c.id FROM ( SELECT * FROM 表名 t1 WHERE t1.superior_id = '57adca6415a414043183326f' ) b JOIN 表名 c ON b.id = c.superior_id UNION ALL SELECT d.id FROM ( SELECT c.id FROM ( SELECT * FROM 表名 t1 WHERE t1.superior_id = '57adca6415a414043183326f' ) b LEFT JOIN 表名 c ON b.id = c.superior_id ) t JOIN 表名 d ON t.id = d.superior_id
此時查詢的id爲:57adca6415a414043183326f的3層如下的全部id,結果以下:
如若換成查詢id爲:test3,則結果爲:
經過這條語句解決了問題,可是尚未在數據量大的狀況下進行測試,並且只是初期效果,各位童鞋有何好的建議,也歡迎拍磚~