mysql遞歸查詢組織機構

轉載自https://blog.csdn.net/moyanxuan_1993_2_24/article/details/52790314

父子查詢: 根據父 id 查詢下面所有子節點數據;子父查詢: 根據子 id 查詢上面所有父節點數據;
                                                                                                           ————mysql遞歸查詢

目錄結構:

創建表,並添加測試數據

創建表

DROP TABLE IF EXISTS vrv_org_tab;
CREATE TABLE vrv_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 KEY unique_org_name (org_name)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

添加數據

INSERT INTO vrv_org_tab VALUES (‘1’, ‘北信源’, ‘1’, ‘0’);
INSERT INTO vrv_org_tab VALUES (‘2’, ‘北京’, ‘2’, ‘1’);
INSERT INTO vrv_org_tab VALUES (‘3’, ‘南京’, ‘2’, ‘1’);
INSERT INTO vrv_org_tab VALUES (‘4’, ‘武漢’, ‘2’, ‘1’);
INSERT INTO vrv_org_tab VALUES (‘5’, ‘上海’, ‘2’, ‘1’);
INSERT INTO vrv_org_tab VALUES (‘6’, ‘北京研發中心’, ‘3’, ‘2’);
INSERT INTO vrv_org_tab VALUES (‘7’, ‘南京研發中心’, ‘3’, ‘3’);
INSERT INTO vrv_org_tab VALUES (‘8’, ‘武漢研發中心’, ‘3’, ‘4’);
INSERT INTO vrv_org_tab VALUES (‘9’, ‘上海研發中心’, ‘3’, ‘5’);
INSERT INTO vrv_org_tab VALUES (‘10’, ‘北京EMM項目組’, ‘4’, ‘6’);
INSERT INTO vrv_org_tab VALUES (‘11’, ‘北京linkdd項目組’, ‘4’, ‘6’);
INSERT INTO vrv_org_tab VALUES (‘12’, ‘南京EMM項目組’, ‘4’, ‘7’);
INSERT INTO vrv_org_tab VALUES (‘13’, ‘南京linkdd項目組’, ‘4’, ‘7’);
INSERT INTO vrv_org_tab VALUES (‘14’, ‘武漢EMM項目組’, ‘4’, ‘8’);
INSERT INTO vrv_org_tab VALUES (‘15’, ‘武漢linkdd項目組’, ‘4’, ‘8’);
INSERT INTO vrv_org_tab VALUES (‘16’, ‘上海EMM項目組’, ‘4’, ‘9’);
INSERT INTO vrv_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

根據函數查詢

這裏寫圖片描述


希望對大家有幫助!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章