mysql查询一个表,实现递归查询

mysql查询一个表,实现递归查询,第1张

给你个网上写的比较好的例子:

方法一:利用函数来得到所有子节点号。

创建一个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 (000 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 (000 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 (001 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 (001 sec)

首先说一下Oracle的递归查询,相信大部分人都知道很简单。无非start with connect by 函数。下面是从pId向子节点递归查询的例子,unId是数据库表中的主键。

如果是从子节点递归到父节点查询,就把start with 换成unid,prior左右对换

下面再讲MySql 的递归查询方式。MySql没有Oracle的强大功能,虽然都是同一个公司的产品。所以只能靠自己写。有很多方法,用sql去循环查询,或者写存储过程,我这里只提供一种。就是新建一个function函数。

表结构不说了,无非就是 Id ,pId,其他列。下面是创建一个递归查询子节点的函数

DROP FUNCTION IF EXISTS queryChildrenPowerInfo;

CREATE FUNCTION `queryChildrenPowerInfo` (powerId VARCHAR(2000))

RETURNS VARCHAR(2000)

BEGIN

DECLARE sTemp VARCHAR(2000);

DECLARE sTempChd VARCHAR(2000);

SET sTemp = '$';

SET sTempChd = cast(powerId as CHAR);

WHILE sTempChd is not NULL DO

SET sTemp = CONCAT(sTemp, ',', sTempChd);

SELECT group_concat(id) INTO sTempChd FROM t_discretionary_power where FIND_IN_SET(pId,sTempChd)>0;

END WHILE;

return sTemp;

END

调用的时候:select  queryChildrenPowerInfo("fa2528924c7e9168014c9bedfe04039c"); 该语句会返回Id和父Id等于传入参数powerId的一个字符串,中间有逗号隔开如图

下面这句代码的意思是,查询出 t_discretionary_power  表中,tid 等于上面查询出的结果集的数据。FIND_IN_SET(A,B)是MYSQL的函数。意思是查找在B集合中有A的数据。相当于In

select t from t_discretionary_power  t where FIND_IN_SET(tid,queryChildrenPowerInfo('fa2528924c7e9168014c9bedfe04039c'))

protected void GetCategory(int cat_level,int i)

{

GetCategory(newcat_id,i+1);

}

数据库是什么数据库

我先假设你是 Oracle 吧。

CREATE TABLE test_tree (

test_id INT NOT NULL,

pid INT,

test_val VARCHAR(10),

PRIMARY KEY (test_id)

);

INSERT INTO test_tree VALUES(1, NULL, 'NET');

INSERT INTO test_tree VALUES(2, 1, 'C#');

INSERT INTO test_tree VALUES(3, 1, 'J#');

INSERT INTO test_tree VALUES(4, 1, 'ASPNET');

INSERT INTO test_tree VALUES(5, 1, 'VBNET');

INSERT INTO test_tree VALUES(6, NULL, 'J2EE');

INSERT INTO test_tree VALUES(7, 6, 'EJB');

INSERT INTO test_tree VALUES(8, 6, 'Servlet');

INSERT INTO test_tree VALUES(9, 6, 'JSP');

INSERT INTO test_tree VALUES(10, NULL, 'Database');

INSERT INTO test_tree VALUES(11, 10, 'DB2');

INSERT INTO test_tree VALUES(12, 10, 'MySQL');

INSERT INTO test_tree VALUES(13, 10, 'Oracle');

INSERT INTO test_tree VALUES(14, 10, 'SQL Server');

INSERT INTO test_tree VALUES(15, 13, 'PL/SQL');

INSERT INTO test_tree VALUES(16, 15, 'Function');

INSERT INTO test_tree VALUES(17, 15, 'Procedure');

INSERT INTO test_tree VALUES(18, 15, 'Package');

INSERT INTO test_tree VALUES(19, 15, 'Cursor');

INSERT INTO test_tree VALUES(20, 14, 'T-SQL');

使用 START WITH CONNECT BY 语句实现树状查询

通过根节点 向下查询子节点

SELECT

LPAD(' ', 2(LEVEL-1)) || test_val AS test_val

FROM

test_tree

START WITH

test_id IN (1, 6, 10)

CONNECT BY PRIOR test_id = pid;

TEST_VAL

-----------------------------------------------------------

NET

C#

J#

ASPNET

VBNET

J2EE

EJB

Servlet

JSP

Database

DB2

TEST_VAL

-----------------------------------------------------------

MySQL

Oracle

PL/SQL

Function

Procedure

Package

Cursor

SQL Server

T-SQL

20 rows selected

这个估计PKId是ParentId的父节点吧

给你举个例子,就只用这两个字段吧,其他的也没多大用

PKId ParentId

1 0

2 0

3 1

4 2

5 1

假设数据是我上边这样的

可以假设每个PKId分别为商品大类,就把1的定义为软件吧,2定义为硬件,3为硬盘,4为ps软件,5为主板

这样的话,你就能看出对应关系了吧?

1和2是最高层的,所以无父节点,所以ParentId为0

3和5都是硬件,所以归属为1

4为软件,所以归属为2

这样的好处是减少多次读取其他表里的无用信息,在一定程度上可以提高效率,当然是指数据量大的时候,数据量小的时候基本没什么区别

作用你自己都说了,其实就是实现自我关联

但是这样有一点不好,在自身有主键外键,如果其中的逻辑关系弄的不太清楚的话,很容易出问题,简单来说就是这样了

function get_category($id){

$str=array();

//$sql = "select from biao where id=$id";查询节点,自己写吧

$result = array('id'=>,'parent_id'=>);//查询结果一个数组格式

if($result){

$str = get_category($result['parent_id']);

$str[]=$result;

}

return $str;

}

}

调用get_category()就行了,$str第一个元素是节点本身,去掉就行了。

你的代码没看明白,因为数据库可以索引,不明白数据库查询为什么还要二分查找,数据库的HASH是最快速的搜索,那我就直接回答:可以把$conn放在变量里面递归,只要不是在递归函数里面再次mysql_connect就不会造成许多连接,至少浪费一点点堆栈空间(内存)。

其次纠正一下:PHP支持全局变量,需要使用global进行申明,例如:

<php

$a=1;

f();

echo $a;

function f(){

global $a;

$a++;

}

>

最后给你说个轻松的,mysql的连接符$conn,其实在所有的mysql函数里面是可以省略的,如果你只有一个连接,这个参数完全可以不用,例如:

<php

mysql_connect('127001','root','123456');

f();

mysql_close();

function f(){

$sql='select ';

$res=mysql_query($sql);//可以正常执行

$row=mysql_fetch_array($res);

mysql_free_result($res);

}

>

以上就是关于mysql查询一个表,实现递归查询全部的内容,包括:mysql查询一个表,实现递归查询、sql语句实现递归查询所有节点,mysql和oracle都能用的、C#用递归的方式遍历数据库中有父ID结构的表时怎样用一个变量保存遍历的深度等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9859552.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-02
下一篇2023-05-02

发表评论

登录后才能评论

评论列表(0条)

    保存