父子查詢: 根據父 id 查詢下面所有子節點數據;子父查詢: 根據子 id 查詢上面所有父節點數據;
————mysql遞歸查詢
目錄結構:
創建表,並添加測試數據
創建表
DROP TABLE IF EXISTS
vrv_org_tab
;
CREATE TABLEvrv_org_tab
(
id
bigint(8) NOT NULL AUTO_INCREMENT,
org_name
varchar(50) NOT NULL,
org_level
int(4) NOT NULL DEFAULT ‘0’,
org_parent_id
bigint(8) NOT NULL DEFAULT ‘0’,
PRIMARY KEY (id
),
UNIQUE KEYunique_org_name
(org_name
)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;
添加數據
INSERT INTO
vrv_org_tab
VALUES (‘1’, ‘北信源’, ‘1’, ‘0’);
INSERT INTOvrv_org_tab
VALUES (‘2’, ‘北京’, ‘2’, ‘1’);
INSERT INTOvrv_org_tab
VALUES (‘3’, ‘南京’, ‘2’, ‘1’);
INSERT INTOvrv_org_tab
VALUES (‘4’, ‘武漢’, ‘2’, ‘1’);
INSERT INTOvrv_org_tab
VALUES (‘5’, ‘上海’, ‘2’, ‘1’);
INSERT INTOvrv_org_tab
VALUES (‘6’, ‘北京研發中心’, ‘3’, ‘2’);
INSERT INTOvrv_org_tab
VALUES (‘7’, ‘南京研發中心’, ‘3’, ‘3’);
INSERT INTOvrv_org_tab
VALUES (‘8’, ‘武漢研發中心’, ‘3’, ‘4’);
INSERT INTOvrv_org_tab
VALUES (‘9’, ‘上海研發中心’, ‘3’, ‘5’);
INSERT INTOvrv_org_tab
VALUES (‘10’, ‘北京EMM項目組’, ‘4’, ‘6’);
INSERT INTOvrv_org_tab
VALUES (‘11’, ‘北京linkdd項目組’, ‘4’, ‘6’);
INSERT INTOvrv_org_tab
VALUES (‘12’, ‘南京EMM項目組’, ‘4’, ‘7’);
INSERT INTOvrv_org_tab
VALUES (‘13’, ‘南京linkdd項目組’, ‘4’, ‘7’);
INSERT INTOvrv_org_tab
VALUES (‘14’, ‘武漢EMM項目組’, ‘4’, ‘8’);
INSERT INTOvrv_org_tab
VALUES (‘15’, ‘武漢linkdd項目組’, ‘4’, ‘8’);
INSERT INTOvrv_org_tab
VALUES (‘16’, ‘上海EMM項目組’, ‘4’, ‘9’);
INSERT INTOvrv_org_tab
VALUES (‘17’, ‘上海linkdd項目組’, ‘4’, ‘9’);
select * from vrv_org_tab;
根據父id遞歸查詢所有子節點
創建函數
create function getChildrenOrg(orgid INT)
returns varchar(4000)
BEGIN
DECLARE oTemp VARCHAR(4000);
DECLARE oTempChild VARCHAR(4000);
SET oTemp = '';
SET oTempChild = CAST(orgid AS CHAR);
WHILE oTempChild IS NOT NULL
DO
SET oTemp = CONCAT(oTemp,',',oTempChild);
SELECT GROUP_CONCAT(id) INTO oTempChild FROM vrv_org_tab WHERE FIND_IN_SET(org_parent_id,oTempChild) > 0;
END WHILE;
RETURN oTemp;
END
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
根據函數查詢
根據子id遞歸查詢所有父節點
根據子id查詢父節點就不那麼麻煩了,不需要寫遞歸函數,當然,你也可以寫遞歸函數來查詢。我這邊提供的是不寫函數的方式。請看代碼
寫sql語句
SELECT id,org_name,org_level,org_parent_id
FROM (
SELECT
@r AS _id,
(SELECT @r := org_parent_id FROM vrv_org_tab WHERE id = _id) AS parent_id,
@l := @l + 1 AS lvl
FROM
(SELECT @r := 10000, @l := 0) vars,
vrv_org_tab h
WHERE @r <> 0) T1
JOIN vrv_org_tab T2
ON T1._id = T2.id
ORDER BY id;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
注意:大家看到那個10000了嗎,就是我們的子節點id。
注意:只支持單個查詢,意思是不可以根據兩個或者兩個以上的子節點同時查詢出所有父節點。我們可以看到,上面參數都是單個值進行遞歸查詢的。
西面提供一個函數支持多個查詢
根據組織機構名稱模糊查詢所有父節點
該功能常用於組織機構模糊搜索
創建函數
CREATE FUNCTION getParentOrgByOrgName(orgName VARCHAR(20))
RETURNS VARCHAR(4000)
BEGIN
DECLARE sPid VARCHAR(1000);
DECLARE sPidTemp VARCHAR(1000);
DECLARE pid VARCHAR(1000);
DECLARE count INT DEFAULT 0;
DECLARE allpid VARCHAR(4000);
SET sPidTemp = '';
SELECT GROUP_CONCAT(DISTINCT(CAST(id AS CHAR))) INTO sPid
FROM vrv_org_tab WHERE org_name LIKE CONCAT('%',orgName,'%');
SET allpid = '';
WHILE count = 0
DO
IF sPid IS NULL THEN
SET allpid = '-1';
SET count = 1;
ELSE
SET pid = SUBSTRING_INDEX(sPid,',',1);
SET sPidTemp = CONCAT(sPidTemp,',',pid);
IF LENGTH(pid) = LENGTH(sPid) THEN
SET count = 1;
SET sPid = SUBSTRING(sPid FROM LENGTH(SUBSTRING_INDEX(sPid,',',1)) FOR LENGTH(sPid)+1);
ELSE
SET sPid = SUBSTRING(sPid FROM LENGTH(SUBSTRING_INDEX(sPid,',',1))+2 FOR LENGTH(sPid)+1);
END IF;
SELECT GROUP_CONCAT(CAST(id AS CHAR)) INTO sPidTemp
FROM (
SELECT
@r AS _id,
(SELECT @r := org_parent_id FROM vrv_org_tab WHERE id = _id) AS parent_id,
@l := @l + 1 AS lvl
FROM
(SELECT @r := pid, @l := 0) vars,
vrv_org_tab h
WHERE @r <> 0) T1
JOIN vrv_org_tab T2
ON T1._id = T2.id;
SET allpid = CONCAT_WS(',',pid,sPidTemp,allpid);
END IF;
END WHILE;
RETURN allpid;
END
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
根據函數查詢
希望對大家有幫助!