树形结构数据查询------数据库篇(利用Sql查询出父节点及其底下所有子节点[包括子节点下的子节点])

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/chengtanyong4777/article/details/84326057

1.背景

最近工作老是会遇到需要根据父节点查询底下所有子节点的业务。心里突然冒出想直接使用sql语句一步到位查询出来的想法,故此尝试了一波,没想到效果还不错,记录下来说不定以后可以继续沿用和改进。也希望能给更多需要的人提供一点帮助。

这里主要介绍一下两种数据库中sql的查询实现。分别为mysql和sqlserver,两者之间的实现方法还是有些不同的。新手一个,还不能深刻的剖析原理,所以多多谅解。话不多说,直接上代码

2.数据准备

2.1数据库表结构如下

大致说明一下

id:数据库自增字段

equip_code:设备编码

equip_name:设备名称

tree_code:自身的节点编码

parent_code:父级节点编码

方便测试,下面是上述表的sql文件,直接到数据库中执行即可。

为了方便,就只提供一个mysql的sql文件,sqlserver要测试的时候自行创建


SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `equip`
-- ----------------------------
DROP TABLE IF EXISTS `equip`;
CREATE TABLE `equip` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `equip_code` varchar(255) DEFAULT NULL COMMENT '设备编码',
  `equip_name` varchar(255) NOT NULL COMMENT '设备名称',
  `tree_code` varchar(255) NOT NULL COMMENT '自身树节点',
  `parent_code` varchar(255) NOT NULL COMMENT '父节点',
  PRIMARY KEY (`id`),
  UNIQUE KEY `tree_code` (`tree_code`)
) ENGINE=InnoDB AUTO_INCREMENT=4304 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of equip
-- ----------------------------
INSERT INTO `equip` VALUES ('3549', '[121]', '测试', '102', '0');
INSERT INTO `equip` VALUES ('3550', null, 'root', '103', '0');
INSERT INTO `equip` VALUES ('3551', '[code0]', '11', '1030001', '103');
INSERT INTO `equip` VALUES ('3552', '[code1]', '11_1AL', '10300010001', '1030001');
INSERT INTO `equip` VALUES ('3553', '[code2]', '11_1AL05_1到达廊照明1', '103000100010001', '10300010001');
INSERT INTO `equip` VALUES ('3554', '[code3]', '11_1AL06_6L3照明总箱1', '103000100010002', '10300010001');
INSERT INTO `equip` VALUES ('3555', '[code4]', '11_1AL08_8贵宾候机照明1', '103000100010003', '10300010001');
INSERT INTO `equip` VALUES ('3556', '[code5]', '11_1AL09_6贵宾候机照明2', '103000100010004', '10300010001');
INSERT INTO `equip` VALUES ('3557', '[code6]', '11_1AL09_7应急照明总箱', '103000100010005', '10300010001');
INSERT INTO `equip` VALUES ('3558', '[code7]', '11_1AL09_8贵宾候机照明3', '103000100010006', '10300010001');
INSERT INTO `equip` VALUES ('3559', '[code8]', '11_1AL10_1配电房照明', '103000100010007', '10300010001');
INSERT INTO `equip` VALUES ('3560', '[code9]', '11_1AL10_5厨房照明', '103000100010008', '10300010001');
INSERT INTO `equip` VALUES ('3561', '[code10]', '11_1AL10_6贵宾候机照明4', '103000100010009', '10300010001');
INSERT INTO `equip` VALUES ('3562', '[code11]', '11_1AL14_7航空障碍灯高杆灯照明', '103000100010010', '10300010001');
INSERT INTO `equip` VALUES ('3563', '[code12]', '11_2AL', '10300010002', '1030001');
INSERT INTO `equip` VALUES ('3564', '[code13]', '11_2AL08_9到达廊照明5', '103000100020001', '10300010002');
INSERT INTO `equip` VALUES ('3565', '[code14]', '11_2AL09_8L3照明总箱2', '103000100020002', '10300010002');
INSERT INTO `equip` VALUES ('3566', '[code15]', '11_2AL10_1到达廊照明2', '103000100020003', '10300010002');
INSERT INTO `equip` VALUES ('3567', '[code16]', '11_2AL10_2到达廊照明3', '103000100020004', '10300010002');
INSERT INTO `equip` VALUES ('3568', '[code17]', '11_2AL10_8到达廊照明4', '103000100020005', '10300010002');
INSERT INTO `equip` VALUES ('3569', '[code18]', '11_2AL12_7航空障碍灯高杆灯照明', '103000100020006', '10300010002');
INSERT INTO `equip` VALUES ('3570', '[code19]', '11_2AL14_4配电房照明', '103000100020007', '10300010002');
INSERT INTO `equip` VALUES ('3571', '[code20]', '11_2AL14_7应急照明总箱', '103000100020008', '10300010002');

3.sql实现

3.1mysql实现

由于所写的sql语句查询的时候不查出自己本身,所以下面的sql语句使用union来将本身拼接上去,若不需要查询自己本身,则可以将union和其之前的sql删掉

select id,equip_code,equip_name,tree_code,parent_code from equip where tree_code = “这里填需要查询的节点tree_code”
union
select id,equip_code,equip_name,tree_code,parent_code from 
(select t1.id,t1.equip_code,t1.equip_name,t1.tree_code,t1.parent_code,IF(FIND_IN_SET(parent_code,@pids)> 0,@pids := CONCAT(@pids,',',tree_code),0) as ischild 
from (select id,equip_code,equip_name,tree_code,parent_code from equip order by tree_code,parent_code) t1,(select @pids := “这里填需要查询的节点tree_code”)t2)t3 where ischild != 0

上述sql语句即可查出本身及其底下所有子节点【包括子节点的子节点的子节点.........】

3.2sqlserver实现

with cte as
	(
		select * from t_c_energy_class_acquisition
		where treePCode = '这里填需要查询的节点tree_code'
		union ALL
		select a.* from t_c_energy_class_acquisition as a,cte as b where     
        a.treePCode=b.treeCode
	)
select * from cte
union
select * from t_c_energy_class_acquisition where treeCode =  '这里填需要查询的节点tree_code'

4.结束语

oracle的暂时还没有用到,所以也没有去研究。若以后用到,会继续更新;若还有更好的方法,也欢迎留言指正!

猜你喜欢

转载自blog.csdn.net/chengtanyong4777/article/details/84326057