在关系型数据库中,常常会设计一种上级下级关系数据,即数据中保存这上级的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,则结果为:
经过这条语句解决了问题,可是尚未在数据量大的状况下进行测试,并且只是初期效果,各位童鞋有何好的建议,也欢迎拍砖~