start with在mysql中的用法

mysql中如何实现start with的层次查询功能

start with是Oracle数据库中的一个关键字,用于实现层次查询,即根据一个根节点,查询出其所有的子节点和后代节点。mysql数据库中没有start with这个关键字,但是可以通过其他的方法来模拟层次查询的功能。本文将介绍三种在mysql中实现层次查询的方法,分别是使用递归函数、使用临时表和使用变量循环赋值。这三种方法各有优缺点,适用于不同的场景和需求。

一、层次查询的概念和示例

层次查询是一种根据数据之间的父子关系,从一个或多个根节点开始,查询出其所有的子节点和后代节点的查询方式。层次查询常用于处理具有树状结构的数据,例如组织机构、产品分类、目录树等。

为了方便说明,我们使用一个简单的组织机构表作为示例,表结构如下:

idnameparent_id

1Anull

2B1

3C1

4D2

5E2

6F3

7Gnull

8H7

其中,id字段是主键,name字段是组织名称,parent_id字段是父组织的id,如果为null表示没有父组织。这个表可以表示如下的树状结构:

如果我们想要从A节点开始,查询出其所有的子节点和后代节点,即B、C、D、E、F,我们可以使用Oracle数据库中的start

with和connect by关键字来实现,语法如下:

其中,start with指定了根节点的条件,connect by指定了连接条件,prior表示上一条记录。这条语句的执行过程大致如下:

1. 先从表中找出满足start with条件的记录,即id = 1的记录,作为第一层结果。

2. 然后根据connect by条件,找出与第一层结果相关联的记录,即parent_id等于第一层结果的id的记录,作为第二层结果。

3. 再根据connect by条件,找出与第二层结果相关联的记录,即parent_id等于第二层结果的id的记录,作为第三层结果。

4. 如此循环,直到没有更多的记录满足connect by条件为止。

5. 最后将所有层次的结果合并返回。

执行结果如下:A├─B│ ├─D│ └─E└─C └─FG└─H

select * from orgstart with id = 1 -- 根节点条件connect by prior id = parent_id -- 连接条件idnameparent_id

1Anull

2B1

3C1

4D2

5E2

6F3

二、在mysql中使用递归函数实现层次查询

mysql数据库中没有start with和connect by这样的关键字来实现层次查询,但是可以通过创建一个递归函数来模拟这个功能。递归函数是一种在函数体内调用自身的函数,可以用来处理具有重复性或分治性质的问题。在mysql中,可以使用create function语句来创建一个自定义的函数,语法如下:

其中,function_name是函数的名称,parameters是函数的参数列表,return_type是函数的返回类型,函数体是函数的执行逻辑。

为了实现层次查询的功能,我们可以创建一个名为get_children的函数,接受一个根节点的id作为参数,返回一个包含其所有子节点和后代节点的id的字符串,用逗号分隔。函数的大致逻辑如下:

1. 定义一个变量result,用来存储结果字符串,初始值为空。

2. 定义一个变量temp,用来存储临时结果字符串,初始值为根节点的id。

3. 定义一个循环,条件为temp不为空。

4. 在循环中,将temp的值追加到result的末尾,并在最后加上一个逗号。

5. 然后根据temp的值,从表中查询出所有与之相关联的记录的id,即parent_id等于temp的id的记录,并将这些id拼接成一个新的字符串,赋值给temp。

6. 重复步骤4和5,直到temp为空为止。

7. 最后返回result去掉最后一个逗号后的值。

具体的代码如下:

创建好这个函数后,我们就可以使用它来实现层次查询了。例如,如果我们想要从A节点开始,查询出其所有的子节点和后代节点,我们可以使用如下语句:

执行结果如下:create function function_name (parameters)returns return_typebegin -- 函数体end

create function get_children (root_id int)returns varchar(1000)begin declare result varchar(1000) default ''; -- 结果字符串 declare temp varchar(1000) default root_id; -- 临时结果字符串 while temp is not null do -- 循环条件 set result = concat(result, temp, ','); -- 将临时结果追加到结果字符串 select group_concat(id) into temp from org where parent_id in (temp); -- 查询下一层结果并赋值给临时结果 end while; return substring(result, 1, length(result) - 1); -- 返回结果去掉最后一个逗号end

select * from org where id in (get_children(1))idnameparent_id

1Anull

2B1

3C1

4D2

5E2

6F3

使用递归函数实现层次查询的优点是简单易懂,逻辑清晰,可以灵活地指定根节点和查询条件。缺点是性能较差,因为每次循环都要执行一次查询,并且需要创建和维护额外的函数。

三、在mysql中使用临时表实现层次查询

除了使用递归函数外,还可以使用临时表来实现层次查询。临时表是一种只存在于当前会话中的表,当会话结束或者主动删除时,临时表也会消失。在mysql中,可以使用create temporary table语句来创建一个临时表,语法如下:

其中,table_name是临时表的名称,columns是临时表的列定义。

为了实现层次查询的功能,我们可以创建一个名为tmp_org的临时表,用来存储每一层的结果。临时表的结构如下:

idnameparent_id

然后我们可以使用如下步骤来实现层次查询:

1. 先从原始表中找出满足根节点条件的记录,并插入到临时表中。

2. 然后根据临时表中的记录,从原始表中查询出所有与之相关联的记录,即parent_id等于临时表中的id的记录,并插入到临时表中。

3. 重复步骤2,直到没有更多的记录可以插入到临时表中为止。

4. 最后从临时表中查询出所有的记录并返回。

具体的代码如下:

执行结果如下:create temporary table table_name (columns)

-- 创建临时表create temporary table tmp_org ( id int, name varchar(10), parent_id int);

-- 插入根节点insert into tmp_orgselect * from org where id = 1;

-- 循环插入子节点和后代节点while (select count(*) from org where parent_id in (select id from tmp_org) and id not in (select id from tmp_org)) > 0 do insert into tmp_org select * from org where parent_id in (select id from tmp_org) and id not in (select id from tmp_org);end while;

-- 查询结果select * from tmp_org;idnameparent_id

1Anull

2B1

3C1

4D2

5E2

6F3

使用临时表实现层次查询的优点是性能较好,因为只需要创建一次临时表,并且可以避免重复查询。缺点是需要占用额外的空间,因为临时表会存储所有层次的结果,而且需要手动删除临时表。

四、在mysql中使用变量循环赋值实现层次查询

除了使用递归函数和临时表外,还可以使用变量循环赋值来实现层次查询。变量循环赋值是一种利用变量的特性,通过循环将变量的值不断更新的方法。在mysql中,可以使用set语句来给变量赋值,语法如下:

其中,@variable_name是变量的名称,expression是变量的值,可以是一个常量、一个列名、一个函数或一个子查询等。

为了实现层次查询的功能,我们可以定义两个变量,分别是@result和@temp,用来存储结果字符串和临时结果字符串。然后我们可以使用如下步骤来实现层次查询:

1. 先给@result和@temp赋值为根节点的id。

2. 定义一个循环,条件为@temp不为空。

3. 在循环中,将@temp的值追加到@result的末尾,并在最后加上一个逗号。

4. 然后根据@temp的值,从表中查询出所有与之相关联的记录的id,并将这些id拼接成一个新的字符串,赋值给@temp。

5. 重复步骤3和4,直到@temp为空为止。

6. 最后根据@result的值,从表中查询出所有满足条件的记录并返回。

具体的代码如下:

执行结果如下:

idnameparent_id

1Anull

2B1

3C1

4D2

5E2

6F

3set @variable_name = expression;

-- 定义变量set @result = '1';set @temp = '1';

-- 循环更新变量while @temp is not null do set @result = concat(@result, ',', @temp); select group_concat(id) into @temp from org where parent_id in (@temp);end while;

-- 查询结果select * from org where id in (@result);

合集下载

oracle start with的用法

oracle start with的用法

Oracle Start With关键字

前言旨在记录一些Oracle使用中遇到的各种各样的问题. 同时希望能帮到和我遇到同样问题的人.

Start With (树查询)

问题描述:

在数据库中, 有一种比较常见得 设计模式, 层级结构 设计模式, 具体到 Oracle table中,

字段特点如下:

ID, DSC, PID;

三个字段, 分别表示 当前标识的 ID(主键), DSC 当前标识的描述, PID 其父级ID, 比较典型的例子 是 国家, 省, 市 这种层级结构;

省份归属于国家, 因此 PID 为 国家的 ID, 以此类推;

create table DEMO (

ID varchar2(10) primary key,

DSC varchar2(100),

PID varchar2(10)

)

--插入几条数据

Insert Into DEMO values ('00001', '中国', '-1');

Insert Into DEMO values ('00011', '陕西', '00001');

Insert Into DEMO values ('00012', '贵州', '00001');

Insert Into DEMO values ('00013', '河南', '00001');

Insert Into DEMO values ('00111', '西安', '00011');

Insert Into DEMO values ('00112', '咸阳', '00011');

Insert Into DEMO values ('00113', '延安', '00011');

这样子就成了一个简单的树级结构, 我一般将 根节点的 PID 定为 -1;

Start With:

基本语法如下:

SELECT ... FROM + 表名

mysql实现startwith

mysql实现startwith

mysql实现startwith

⾃⼰写service----> 传⼊map(idsql,rssql,prior) idsql 查询id rssql 查询结果集 调⽤ 以下⽅法

@param ids 要查询的起始 start with

* @param allres 包含要递归数据的结果集 ( 查询时别名ID PID )

* @param pos prior---> UP or DOWN

* @return

*/

public static List> getTree(ArrayList ids,

List> allres,String pos) {

List> res=new ArrayList>();

if("up".equals(pos)){

res=toCreatTreeUp(ids,allres,res);

}

if("down".equals(pos)){

res=toCreatTreeDown(ids,allres,res);

}

return res;

}

private static List> toCreatTreeUp(ArrayList ids,

List> allres,List> res) {

ArrayList idss = new ArrayList();

for(String id :ids){

for (Map map : allres) {

if(id.equals(map.get("ID").toString())){

idss.add(map.get("PID").toString());

res.add(map);

}

}

}

if (idss.size()!=0) {

ids = idss;

res = toCreatTreeUp(ids,allres,res);

}

return res ;

}

private static List> toCreatTreeDown(ArrayList ids,

List> allres,List> res) {

MySql 主键自动增长

MySql 主键自动增长

MySql 主键自动增长

Mysql,SqlServer,Oracle主键自动增长设置

1、把主键定义为自动增长标识符类型

MySql

在mysql中,如果把表的主键设为auto_increment类型,数据库就会自动为主键赋值。例如:

createtable customers(id intauto_incrementprimarykeynotnull, name varchar(15));

insertinto customers(name) values("name1"),("name2");

select id from customers;

以上sql语句先创建了customers表,然后插入两条记录,在插入时仅仅设定了name字段的值。最后查询表中id字段,查询结果为:

由此可见,一旦把id设为auto_increment类型,mysql数据库会自动按递增的方式为主键赋值。

Sql Server

在MS SQLServer中,如果把表的主键设为identity类型,数据库就会自动为主键赋值。例如:

createtable customers(id intidentity(1,1) primarykeynotnull, name varchar(15));

insertinto customers(name) values('name1'),('name2');

select id from customers;

注意:在sqlserver中字符串用单引号扩起来,而在mysql中可以使用双引号。

查询结果和mysql的一样。

由此可见,一旦把id设为identity类型,MS SQLServer数据库会自动按递增的方式为主键赋值。identity包含两个参数,第一个参数表示起始值,第二个参数表示增量。 以前经常会碰到这样的问题,当我们删除了一条自增长列为1的记录以后,再次插入的记录自增长列是2了。我们想在插入一条自增长列为1的记录是做不到的。今天跟同事讨论的时候发现可以通过设置SET IDENTITY_INSERT ON;来取消自增长,等我们插入完数据以后在关闭这个功能。实验如下:

自动增长字段

自动增长字段

⾃动增长字段

在设计数据库的时候,有时需要表的某个字段是⾃动增长的,最常使⽤⾃动增长字段的就是表的主键,使⽤⾃动增长字段可以简化主键的⽣成。不同的DBMS 中⾃动增长字段的实现机制也有不同,下⾯分别介绍。

MYSQL中的⾃动增长字段

MYSQL中设定⼀个字段为⾃动增长字段⾮常简单,只要在表定义中指定字段为AUTO_INCREMENT即可。⽐如下⾯的SQL语句创建T_Person表,其中主键FId为⾃动增长字段:

CREATE TABLE T_Person(FId INT PRIMARY KEYAUTO_INCREMENT,FName VARCHAR(20),FAge INT);

执⾏上⾯的SQL 语句后就创建成功了T_Person 表,然后执⾏下⾯的SQL 语句向T_Person表中插⼊⼀些数据:

INSERT INTO T_Person(FName,FAge)VALUES(‘Tom’,18);

INSERT INTO T_Person(FName,FAge)VALUES(‘Jim’,81);

INSERT INTO T_Person(FName,FAge)VALUES(‘Kerry’,33);

注意这⾥的INSERT语句没有为FId字段设定任何值,因为DBMS会⾃动为FId字段设定值。执⾏完毕后查看T_Person表中的内容:

FId FName FAge

1 Tom 18

2 Jim 81

3 Kerry 33

可以看到FId中确实是⾃动增长的。

MSSQLServer 中的⾃动增长字段

MSSQLServer中设定⼀个字段为⾃动增长字段⾮只要在表定义中指定字段为IDENTITY即可,格式为IDENTITY(startvalue,step),其中的startvalue参数值为起始数字,step参数值为步长,即每次⾃动增长时增加的值。

⽐如下⾯的SQL语句创建T_Person表,其中主键FId为⾃动增长字段,并且设定100 为起始数字,步长为3:

mysql中connet by level用法 -回复

mysql中connet by level用法 -回复

mysql中connet by level用法 -回复

MySQL中的CONNECT BY LEVEL用法

概述:

MySQL是一种常用的关系型数据库管理系统,广泛应用于各种数据应用场景中。在MySQL中,CONNECT BY LEVEL是一种用于构建层次结构的特殊语法。本文将详细介绍CONNECT BY LEVEL的用法和步骤,以帮助读者更好地理解和使用这一功能。

CONNECT BY LEVEL的概念:

CONNECT BY LEVEL是一种递归查询语法,通常用于处理具有层次结构的数据。它基于一个"伪"列LEVEL,该列表示查询结果集中每一行的层次级别。利用CONNECT BY LEVEL,我们可以轻松地在MYSQL中实现对层次数据的操作。

CONNECT BY LEVEL的语法:

CONNECT BY LEVEL的语法非常简单,其一般形式如下所示:

SELECT column1, column2, ...

FROM table

WHERE condition

START WITH condition

CONNECT BY condition;

其中,column1, column2, ... 是要查询的列名;table是要查询的表名;condition是查询的条件。START WITH是设置查询的起始点,可以是一个具体的条件或者NULL。CONNECT BY是用于定义递归的连接条件。

CONNECT BY LEVEL的具体用法:

下面将一步一步地说明CONNECT BY LEVEL的具体用法,以便读者更好地理解和使用。

第一步:创建测试环境

首先,我们需要创建一个测试表,用于演示CONNECT BY LEVEL的用法。假设我们要创建一个部门表,包含部门编号和上级部门编号两列。创建表的SQL语句如下:

CREATE TABLE departments (

dept_id INT PRIMARY KEY,

mysql实现oraclestartwithconnectby递归

mysql实现oraclestartwithconnectby递归

mysql实现oraclestartwithconnectby递归

在Oracle 中我们知道有⼀个 Hierarchical Queries 通过CONNECT BY 我们可以⽅便的查了所有当前节点下的所有⼦节点。但很遗憾,在MySQL的⽬前版本中还没有对应的功能。

在MySQL中如果是有限的层次,⽐如我们事先如果可以确定这个树的最⼤深度是4, 那么所有节点为根的树的深度均不会超过4,则我们可以

直接通过left join 来实现。

但很多时候我们⽆法控制树的深度。这时就需要在MySQL中⽤存储过程来实现或在你的程序中来实现这个递归。本⽂讨论⼀下⼏种实现的

⽅法。

样例数据:

mysql> create table treeNodes

-> (

-> id int primary key,

-> nodename varchar(20),

-> pid int

-> );

Query OK, 0 rows affected (0.09 sec)

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

mysql with子句

mysql with子句

MySQL是一种开源的关系型数据库管理系统,常用于存储和管理大量结构化数据。在进行数据库查询时,使用WITH子句可以方便地创建临时表并将其与查询结果进行关联。下面列举了10个关于MySQL

WITH子句的使用场景和示例。

1. 递归查询

WITH子句可以用于实现递归查询,例如查询员工及其所有下属的信息。以下是一个示例:

```

WITH RECURSIVE EmployeeHierarchy AS (

SELECT employee_id, employee_name, manager_id

FROM Employee

WHERE manager_id IS NULL

UNION ALL

SELECT e.employee_id, e.employee_name, e.manager_id

FROM Employee e

INNER JOIN EmployeeHierarchy eh ON e.manager_id =

eh.employee_id

)

SELECT *

FROM EmployeeHierarchy;

``` 该查询会返回所有员工及其对应的上级员工的信息。

2. 分组查询

WITH子句可以用于创建临时表并进行分组查询。以下是一个示例:

```

WITH DepartmentTotal AS (

SELECT department_id, SUM(salary) AS total_salary

FROM Employee

GROUP BY department_id

)

SELECT department_id, total_salary

FROM DepartmentTotal;

```

该查询会返回每个部门的总工资。

3. 多重WITH子句

可以在一个查询中使用多个WITH子句,各个子句之间用逗号分隔。以下是一个示例:

oracle中start with在mysql中的用法(一)

oracle中start with在mysql中的用法(一)

Oracle中start with在MySQL中的用法

介绍

在Oracle数据库中,有一个非常有用的start with语句,它可以用于构建以某个节点为起点的递归查询。然而,在MySQL数据库中,并没有直接对应的语法。本文将介绍在MySQL中实现类似功能的一些方法。

方法一:使用连接查询

使用连接查询是一种常见的在MySQL中实现递归查询的方法。它通过多次连接同一数据库表来模拟Oracle中start with的功能。

步骤如下: 1. 创建一个临时表,用于保存中间结果。 2. 将起始节点插入临时表。 3. 循环执行以下步骤,直到找到所有递归节点或达到指定的递归深度。 - 将临时表与原表进行连接,并将连接的结果插入临时表。 - 如果没有新的结果被插入临时表,则停止循环。 4.

最后,从临时表中获取所有递归结果。

示例代码如下:

-- 创建临时表

CREATE TEMPORARY TABLE temp_table (id INT);

-- 插入起始节点

INSERT INTO temp_table VALUES (起始节点);

-- 循环查询

SET @level = 0;

WHILE EXISTS (SELECT * FROM temp_table) AND @level < 最大递归深度 DO

-- 连接查询并插入结果

INSERT INTO temp_table

SELECT t.* FROM temp_table AS tt

JOIN original_table AS t ON = _id;

-- 更新递归深度

SET @level = @level + 1;

END WHILE;

-- 获取递归结果

SELECT * FROM temp_table;

方法二:使用存储过程

mysql with子句 2

mysql with子句

MySQL是一种常用的关系型数据库管理系统,可以通过使用WITH子句来实现更复杂的查询和数据操作。WITH子句也被称为临时表,它允许我们在查询中创建一个临时的结果集,然后在后续的查询中引用该结果集。下面是一些关于MySQL WITH子句的例子:

1. 使用WITH子句创建一个临时表:

```

WITH temp_table AS (

SELECT * FROM customers WHERE age > 30

)

SELECT * FROM temp_table;

```

这个例子中,我们使用WITH子句创建了一个名为temp_table的临时表,然后在后续的查询中引用了这个临时表。

2. 使用WITH子句实现递归查询:

```

WITH recursive_query AS (

SELECT employee_id, manager_id FROM employees WHERE

employee_id = 1

UNION ALL

SELECT e.employee_id, e.manager_id FROM employees e JOIN recursive_query r ON e.employee_id = r.manager_id

)

SELECT * FROM recursive_query;

```

这个例子中,我们使用WITH子句创建了一个名为recursive_query的临时表,并在后续的查询中使用了递归查询来获取员工1的所有直接和间接下属。

3. 使用WITH子句实现分组查询:

```

WITH sales_total AS (

SELECT product_id, SUM(quantity) AS total_sales FROM

sales GROUP BY product_id

)

SELECT p.product_name, st.total_sales FROM products p

oracle中start with在mysql中的用法

oracle中start with在mysql中的用法

在MySQL中,可以使用递归查询来实现Oracle中的START

WITH语法。

在Oracle中,START WITH语法用于指定递归查询的基础条件。在MySQL中,可以使用WITH RECURSIVE关键字来实现递归查询,类似于Oracle的START WITH。

下面是一个示例,演示如何在MySQL中使用递归查询实现Oracle中的START WITH:

```

WITH RECURSIVE cte (id, name, parent_id, level) AS (

SELECT id, name, parent_id, 0 AS level

FROM your_table

WHERE id = 1 -- START WITH条件

UNION ALL

SELECT t.id, , t.parent_id, cte.level + 1

FROM your_table t

INNER JOIN cte ON t.parent_id = cte.id

)

SELECT *

FROM cte

ORDER BY level;

```

在上面的查询中,cte是递归查询的临时表名。在WITH RECURSIVE子句中,首先选择起始记录(根据START

WITH条件),然后使用UNION ALL和递归连接子句来递归查询与起始记录相关的子记录。每次递归查询时,通过连接cte表自身来查找下一级的记录,直到没有更多的记录匹配为止。

最后,查询从cte表中选择所有的记录,并按照level字段进行排序,以便按照层次结构的顺序返回结果。

请注意,上面的示例仅演示了如何使用递归查询来实现Oracle中的START WITH功能。具体的递归查询语法可能因为MySQL的版本和具体的数据表结构而有所不同,您可能需要根据实际情况进行相应的调整。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
相关文档
最新文档