1. 程式人生 > >Mysql中的遞迴層次查詢(根據父節點查詢所有的子節點和根據子節點查詢所有的父節點)的兩種運用

Mysql中的遞迴層次查詢(根據父節點查詢所有的子節點和根據子節點查詢所有的父節點)的兩種運用

1、根據子節點查詢所有的父節點

建立getParentList函式

SQL語句如下:

delimiter //
CREATEFUNCTION `getParentList`(rootId INT)
RETURNS varchar(1000)

BEGIN
DECLARE sTempVARCHAR(1000);
DECLARE sTempParVARCHAR(1000);
SET sTemp ='';
SET sTempPar =rootId;

#迴圈遞迴
WHILE sTempPar is not null DO
#判斷是否是第一個,不加的話第一個會為空
IF sTemp !='' THEN
SET sTemp =concat(sTemp,',',sTempPar);
ELSE
SET sTemp = sTempPar;
ENDIF;

SET sTemp =concat(sTemp,',',sTempPar);
SELECTgroup_concat(pid) INTO sTempPar FROM province where pid<>idand FIND_IN_SET(id,sTempPar)>0;
ENDWHILE;

RETURN sTemp;
END
//


此時Mysql可能會報如下錯誤:


解決方法:

執行此語句:show VARIABLES like "log_bin_trust_function_creators";

發現log_bin_trust_function_creators的值為OFF(這是預設值)

那麼,我們再執行語句:set global log_bin_trust_function_creators = 1;

現在再來檢視log_bin_trust_function_creators的值已經變為ON了


最後,函式就可以建立成功了。

新建一張資料表province

執行以下sql語句:

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for province
-- ----------------------------
DROP TABLE IF EXISTS `province`;
CREATE TABLE `province` (
  `id` int(10) NOT NULL,
  `name` varchar(10) NOT NULL,
  `pid` int(10) unsigned NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of province
-- ----------------------------
INSERT INTO `province` VALUES ('1', '福建', '0');
INSERT INTO `province` VALUES ('2', '湖南', '0');
INSERT INTO `province` VALUES ('3', '湖北', '0');
INSERT INTO `province` VALUES ('4', '長沙', '2');
INSERT INTO `province` VALUES ('5', '郴州', '2');
INSERT INTO `province` VALUES ('6', '武漢', '3');
INSERT INTO `province` VALUES ('7', '武昌', '3');
INSERT INTO `province` VALUES ('8', '廈門', '1');
INSERT INTO `province` VALUES ('9', '福州', '1');
INSERT INTO `province` VALUES ('10', '泉州', '1');
INSERT INTO `province` VALUES ('11', '閩侯', '9');
INSERT INTO `province` VALUES ('12', '長樂', '9');
INSERT INTO `province` VALUES ('13', '安溪', '10');
INSERT INTO `province` VALUES ('14', '晉江', '10');
INSERT INTO `province` VALUES ('15', '鳳城', '13');
INSERT INTO `province` VALUES ('16', '參內', '13');
INSERT INTO `province` VALUES ('17', '龍湖', '15');


建立成功,如圖:


執行查詢語句:select * from province where FIND_IN_SET(id,getParentList(17))

查詢結果:

2、根據父節點查詢所有的子節點

建立函式getChildrenList

SQL語句如下:

delimiter //
CREATE FUNCTION `getChildrenList`(rootId INT)
RETURNS varchar(1000)


BEGIN
DECLARE sTemp VARCHAR(1000);
DECLARE sTempChd VARCHAR(1000);


SET sTemp = '$';
SET sTempChd =cast(rootId as CHAR);


WHILE sTempChd is not null DO
SET sTemp = concat(sTemp,',',sTempChd);
SELECT group_concat(id) INTO sTempChd FROM province where FIND_IN_SET(pid,sTempChd)>0;
END WHILE;
RETURN sTemp;
END
//


執行查詢語句:select * from province where FIND_IN_SET(id,getChildrenList(1))

查詢結果如下: