mysql 实现 connect by start with

8 篇文章 1 订阅

一 前言

1、mysql没有层级查询方法 而 oracle通过connect by  start with语法可以实现层级查询

2、mysql实现层级查询的方式很多,有使用存储过程函数嵌套调用亦有使用临时表进行层级查询

3、本文使用一种变量循环赋值方式进行,可以套用模版

二 实验

-- 创建测试表
-- DROP TABLE IF EXISTS `test_tree`;
CREATE TABLE `test_tree` (
  `id` varchar(10) DEFAULT NULL,
  `name` varchar(10) DEFAULT NULL,
  `pId` varchar(10) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- 创建测试数据(根节点默认-1)
INSERT INTO `test_tree` VALUES ('1', '中国', '-1');
INSERT INTO `test_tree` VALUES ('2', '福建省', '1');
INSERT INTO `test_tree` VALUES ('3', '海南省', '1');
INSERT INTO `test_tree` VALUES ('4', '泉州市', '2');
INSERT INTO `test_tree` VALUES ('5', '福州市', '2');
INSERT INTO `test_tree` VALUES ('6', '泉港区', '4');
INSERT INTO `test_tree` VALUES ('7', '惠安县', '4');
-- 模版 表名代替test_tree  用id替换以下id 用pid替换以下 用其他从属字段替换name
SELECT
 name,
 id,
 pid,
 @le:= IF (pid = -1 ,0,IF( LOCATE( CONCAT('|',pid,':'),@pathlevel) > 0,SUBSTRING_INDEX( SUBSTRING_INDEX(@pathlevel,CONCAT('|',pid,':'),-1),'|',1) +1,@le+1) ) levels,
 @pathlevel:= CONCAT(@pathlevel,'|',id,':', @le ,'|') pathlevel,
 @pathnodes:= IF( pid =-1,',root', CONCAT_WS(',',IF( LOCATE( CONCAT('|',pid,':'),@pathall) > 0 ,SUBSTRING_INDEX( SUBSTRING_INDEX(@pathall,CONCAT('|',pid,':'),-1),'|',1),@pathnodes ) ,pid ) )paths,
 @pathall:=CONCAT(@pathall,'|',id,':', @pathnodes ,'|') pathall 
FROM test_tree, 
(
 SELECT 
 @le:=0,
 @pathlevel:='', 
 @pathall:='',
 @pathnodes:=''
)  vv
ORDER BY pid,id
 
-- 结合instr(paths,'想要查所有子集的父级id')>0 验证
SELECT
name,
id,
pid,
levels,
paths
FROM (
	SELECT
	 name,
	 id,
	 pid,
	 @le:= IF (pid = -1 ,0,IF( LOCATE( CONCAT('|',pid,':'),@pathlevel) > 0,SUBSTRING_INDEX( SUBSTRING_INDEX(@pathlevel,CONCAT('|',pid,':'),-1),'|',1) +1,@le+1) ) levels,
	 @pathlevel:= CONCAT(@pathlevel,'|',id,':', @le ,'|') pathlevel,
	 @pathnodes:= IF( pid =-1,',root', CONCAT_WS(',',IF( LOCATE( CONCAT('|',pid,':'),@pathall) > 0 ,SUBSTRING_INDEX( SUBSTRING_INDEX(@pathall,CONCAT('|',pid,':'),-1),'|',1),@pathnodes ) ,pid ) )paths,
	 @pathall:=CONCAT(@pathall,'|',id,':', @pathnodes ,'|') pathall 
	FROM test_tree, 
	(
	 SELECT 
	 @le:=0,
	 @pathlevel:='', 
	 @pathall:='',
	 @pathnodes:=''
	)  vv
	ORDER BY pid,id
) src
WHERE instr(paths,'-1')>0
ORDER BY pid

三 验证结果

1、数据

2 查询中国

SELECT
name,
id,
pid,
levels,
paths
FROM (
	SELECT
	 name,
	 id,
	 pid,
	 @le:= IF (pid = -1 ,0,IF( LOCATE( CONCAT('|',pid,':'),@pathlevel) > 0,SUBSTRING_INDEX( SUBSTRING_INDEX(@pathlevel,CONCAT('|',pid,':'),-1),'|',1) +1,@le+1) ) levels,
	 @pathlevel:= CONCAT(@pathlevel,'|',id,':', @le ,'|') pathlevel,
	 @pathnodes:= IF( pid =-1,',root', CONCAT_WS(',',IF( LOCATE( CONCAT('|',pid,':'),@pathall) > 0 ,SUBSTRING_INDEX( SUBSTRING_INDEX(@pathall,CONCAT('|',pid,':'),-1),'|',1),@pathnodes ) ,pid ) )paths,
	 @pathall:=CONCAT(@pathall,'|',id,':', @pathnodes ,'|') pathall 
	FROM test_tree, 
	(
	 SELECT 
	 @le:=0,
	 @pathlevel:='', 
	 @pathall:='',
	 @pathnodes:=''
	)  vv
	ORDER BY pid,id
) src
WHERE instr(paths,'1')>0
ORDER BY pid

3 查询福建省

SELECT
name,
id,
pid,
levels,
paths
FROM (
	SELECT
	 name,
	 id,
	 pid,
	 @le:= IF (pid = -1 ,0,IF( LOCATE( CONCAT('|',pid,':'),@pathlevel) > 0,SUBSTRING_INDEX( SUBSTRING_INDEX(@pathlevel,CONCAT('|',pid,':'),-1),'|',1) +1,@le+1) ) levels,
	 @pathlevel:= CONCAT(@pathlevel,'|',id,':', @le ,'|') pathlevel,
	 @pathnodes:= IF( pid =-1,',root', CONCAT_WS(',',IF( LOCATE( CONCAT('|',pid,':'),@pathall) > 0 ,SUBSTRING_INDEX( SUBSTRING_INDEX(@pathall,CONCAT('|',pid,':'),-1),'|',1),@pathnodes ) ,pid ) )paths,
	 @pathall:=CONCAT(@pathall,'|',id,':', @pathnodes ,'|') pathall 
	FROM test_tree, 
	(
	 SELECT 
	 @le:=0,
	 @pathlevel:='', 
	 @pathall:='',
	 @pathnodes:=''
	)  vv
	ORDER BY pid,id
) src
WHERE instr(paths,'2')>0
ORDER BY pid

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Mars'Ares

请我喝杯咖啡吧

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值