ホームページ > データベース > mysql チュートリアル > mysql的逆袭:如何做递归层次查询_MySQL

mysql的逆袭:如何做递归层次查询_MySQL

WBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWBOYWB
リリース: 2016-06-01 13:40:55
オリジナル
821 人が閲覧しました

bitsCN.com
mysql的逆袭:如何做递归层次查询 最近在做一个从oracle数据库到mysql数据库的移植,遇到一个这样的问题      在Oracle 中我们知道有一个 Hierarchical Queries 通过CONNECT BY 我们可以方便的查了所有当前节点下的所有子节点。但shi,在MySQL的目前版本中还没有对应的函数!!!  换句话来说,想要用mysql实现递归查询,根本做不到!!! 可是经过我数天茶不思饭不想的刻苦琢磨,终于想到了一个合理的,适用于mysql和其他sql的解决方案。   方案一出,就秋风扫落叶之势,席卷整个dao层~~~所到之处,所有问题迎刃而解,让所有问题都不再为问题 都成为了我这个函数的炮灰而已。。。  话不多说待我把解决方法仔细道来~~~~~  下面是sql脚本,想要运行一下 把下边的粘贴复制下来,做一个treenodes.sq直接运行便是。。。 /* Navicat MySQL Data Transfer  Source Server         : mysql_demo3 Source Server Version : 50521 Source Host           : localhost:3306 Source Database       : test  Target Server Type    : MYSQL Target Server Version : 50521 File Encoding         : 65001    Date: 2012-09-02 21:16:03 */  SET FOREIGN_KEY_CHECKS=0;  -- ---------------------------- -- Table structure for `treenodes` -- ---------------------------- DROP TABLE IF EXISTS `treenodes`; CREATE TABLE `treenodes` (   `id` int(11) NOT NULL,   `nodename` varchar(20) DEFAULT NULL,   `pid` int(11) DEFAULT NULL,   PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1;  -- ---------------------------- -- Records of treenodes -- ---------------------------- INSERT INTO `treenodes` VALUES ('1', 'A', '0'); INSERT INTO `treenodes` VALUES ('2', 'B', '1'); INSERT INTO `treenodes` VALUES ('3', 'C', '1'); INSERT INTO `treenodes` VALUES ('4', 'D', '2'); INSERT INTO `treenodes` VALUES ('5', 'E', '2'); INSERT INTO `treenodes` VALUES ('6', 'F', '3'); INSERT INTO `treenodes` VALUES ('7', 'G', '6'); INSERT INTO `treenodes` VALUES ('8', 'H', '0'); INSERT INTO `treenodes` VALUES ('9', 'I', '8'); INSERT INTO `treenodes` VALUES ('10', 'J', '8'); INSERT INTO `treenodes` VALUES ('11', 'K', '8'); INSERT INTO `treenodes` VALUES ('12', 'L', '9'); INSERT INTO `treenodes` VALUES ('13', 'M', '9'); INSERT INTO `treenodes` VALUES ('14', 'N', '12'); INSERT INTO `treenodes` VALUES ('15', 'O', '12'); INSERT INTO `treenodes` VALUES ('16', 'P', '15'); INSERT INTO `treenodes` VALUES ('17', 'Q', '15');    --------------------------------------------------- 上边是sql脚本,在执行select * 之后显示的结果集如下所示: mysql> select * from treenodes; +----+----------+------+ | id | nodename | pid  | +----+----------+------+ |  1 | A        |    0 | |  2 | B        |    1 | |  3 | C        |    1 | |  4 | D        |    2 | |  5 | E        |    2 | |  6 | F        |    3 | |  7 | G        |    6 | |  8 | H        |    0 | |  9 | I        |    8 | | 10 | J        |    8 | | 11 | K        |    8 | | 12 | L        |    9 | | 13 | M        |    9 | | 14 | N        |   12 | | 15 | O        |   12 | | 16 | P        |   15 | | 17 | Q        |   15 | +----+----------+------+ 17 rows in set (0.00 sec)  树形图如下 1:A   +-- 2:B   |    +-- 4:D   |    +-- 5:E   +-- 3:C        +-- 6:F             +-- 7:G 8:H   +-- 9:I   |    +-- 12:L   |    |    +--14:N   |    |    +--15:O   |    |        +--16:P   |    |        +--17:Q   |    +-- 13:M   +-- 10:J   +-- 11:K   --------------------------------------------  如果给你一个这样的table,让你查询根节点为1下的所有节点记录(注意也包括根节点),,肿麽办????? 可能有不少人想到connect by 函数,但是我灰常遗憾的告诉你,咱这儿是mysql!!!  好,客观您勒上眼,,我的解决办法是 利用函数来得到所有子节点号。  闲话少续,看我的解决方法 创建一个function getChildLst, 得到一个由所有子节点号组成的字符串.   mysql> delimiter // mysql> mysql> CREATE FUNCTION `getChildLst`(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 treeNodes where FIND_IN_SET(pid,sTempChd)>0;     ->   END WHILE;     ->   RETURN sTemp;     -> END     -> // Query OK, 0 rows affected (0.00 sec)  mysql> mysql> delimiter ;    使用我们直接利用find_in_set函数配合这个getChildlst来查找  mysql> select getChildLst(1); +-----------------+ | getChildLst(1)  | +-----------------+ | $,1,2,3,4,5,6,7 | +-----------------+ 1 row in set (0.00 sec)  mysql> select * from treeNodes     -> where FIND_IN_SET(id, getChildLst(1)); +----+----------+------+ | id | nodename | pid  | +----+----------+------+ |  1 | A        |    0 | |  2 | B        |    1 | |  3 | C        |    1 | |  4 | D        |    2 | |  5 | E        |    2 | |  6 | F        |    3 | |  7 | G        |    6 | +----+----------+------+ 7 rows in set (0.01 sec)  mysql> select * from treeNodes     -> where FIND_IN_SET(id, getChildLst(3)); +----+----------+------+ | id | nodename | pid  | +----+----------+------+ |  3 | C        |    1 | |  6 | F        |    3 | |  7 | G        |    6 | +----+----------+------+ 3 rows in set (0.01 sec)  -------------------------------------------- 只要按我的做,百发百中弹无虚发,遇到问题万变不离其宗直接粘贴复制就是。。。  补充: 还可以做嵌套查询: select id,pid from treeNodes where id in(      select id from treeNodes where FIND_IN_SET(id, getChildLst(3)) ); 子查询的结果集是    +--------+ id ---- 3 6 7 +-------+ 然后经过外层查询就是  id  pid 3   1 6   3 6   6 --------- 好了 Perfect
  bitsCN.com

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート