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 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
⾃⼰写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,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中的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递归
在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的版本和具体的数据表结构而有所不同,您可能需要根据实际情况进行相应的调整。
