第5步---MySQL的DQL查询语句

第5步---MySQL的DQL查询语句

 DQL 数据库查询语言

 1.基本的查询语句

1.完整得查询得语句

简化版的查询语句

 

select * from 表名 where 条件;

2.创建用于测试的表

1.创建测试数据


-- =================================DQL=================================
-- 创建测试表
DROP TABLE IF EXISTS product;
CREATE TABLE IF NOT EXISTS product(
pid int PRIMARY KEY  auto_increment COMMENT '商品编号',
pname  VARCHAR(20)  not null COMMENT '商品名称',
price  DOUBLE COMMENT '价格',
category_id  VARCHAR(20) COMMENT '商品类别'
)-- 添加测试数据
INSERT INTO product VALUES 
(NULL,'苹果',5000,'c001'),
(NULL,'香蕉',50,'c001'),
(NULL,'西红柿',6000,'c001'),
(NULL,'西瓜',3000,'c001'),
(NULL,'杨桃',5500,'c001'),
(NULL,'手机',7000,'c001');INSERT INTO product VALUES 
(NULL,'苹果',5000,'c002'),
(NULL,'香蕉',50,'c002'),
(NULL,'西红柿',6000,'c002'),
(NULL,'西瓜',3000,'c002'),
(NULL,'杨桃',5500,'c002'),
(NULL,'手机',7000,'c002');INSERT INTO product VALUES 
(NULL,'苹果',5000,'c003'),
(NULL,'香蕉',50,'c003'),
(NULL,'西红柿',6000,'c003'),
(NULL,'西瓜',3000,'c003'),
(NULL,'杨桃',5500,'c003'),
(NULL,'手机',7000,'c003');INSERT INTO product VALUES 
(NULL,'苹果',5000,'c004'),
(NULL,'香蕉',50,'c004'),
(NULL,'西红柿',6000,'c004'),
(NULL,'西瓜',3000,'c004'),
(NULL,'杨桃',5500,'c004'),
(NULL,'手机',7000,'c004');

2.基本的查询


-- 查询所有的数据
SELECT * FROM product;-- 查询指定的列的数据
SELECT  pid,pname ,price,category_id FROM product;
SELECT  pid,pname FROM product;-- 起表别名
-- 多表查询中是可以给的
SELECT * FROM product p;
SELECT * FROM product as p;-- 列别名
SELECT pid AS ppid FROM product;
SELECT pid AS 编码 FROM product;-- 去重
SELECT DISTINCT price FROM product;-- 去除所有列都一样的数据
SELECT DISTINCT * FROM product;-- 表达式查询
SELECT  price ,price+10  new_price  FROM product;

3.运算符

1.算数运算符:加减乘除 /或者div %或者mod

2.比较:条件查询。null和所有的值都是不相等的。

 3.逻辑:

 4.位:

 3.1算数运算符

-- =============================算数运算符号=======================
-- 基本操作
SELECT 6+4;
SELECT 6-4;
SELECT 6*4;
SELECT 6/4;
SELECT 6%4;
SELECT 6 div 4;
SELECT 6 mod 4;-- 所有的商品+10元
SELECT  price ,price+10  new_price  FROM product;--  所有的商品增加10%元
SELECT  price ,price*(1.1)  new_price  FROM product;-- 所有的商品+10元
SELECT  price ,price+10  new_price  FROM product;--  所有的商品增加10%元
SELECT  price ,price*(1.1)  new_price  FROM product;-- 找苹果商品的所有的信息
SELECT *FROM product WHERE pname ='苹果';-- 找出价格为5000的商品
SELECT *FROM product WHERE price =5000;-- 查询价格不是5000的商品
SELECT *FROM product WHERE price !=5000;
SELECT *FROM product WHERE price <>5000;
SELECT *FROM product WHERE  not price =5000;
SELECT *FROM product WHERE   price not in (5000);-- 查询价格> 5000的商品
SELECT *FROM product WHERE price > 5000;-- 查询价格5000到7000之间的的商品
SELECT *FROM product WHERE price BETWEEN  5000 AND 7000;
SELECT *FROM product WHERE price  >=5000 AND price <= 7000;-- 查询价格5000或7000的商品
SELECT *FROM product WHERE price =5000 or price = 7000;
SELECT *FROM product WHERE price in (5000 , 7000);-- 查询含有果的词
-- %任意字符
-- 前面任意
SELECT *FROM product WHERE pname LIKE '%果';
-- 后面任意
SELECT *FROM product WHERE pname LIKE '果%';
-- 前后任意
SELECT *FROM product WHERE pname LIKE '%果%';-- 下划线匹配单个字符
-- 查询第二个字含有果的词
SELECT *FROM product WHERE pname LIKE '_果%';注意:坚决不能使用等号!!!
-- 查询类别不为null的所有的数据
SELECT *FROM product WHERE category_id IS NOT NULL;-- 查询类别为null的所有的数据
SELECT *FROM product WHERE category_id IS  NULL;-- 求几个值的最小值
SELECT LEAST(10,20,5) as small_number;-- 求几个值的最大值
SELECT GREATEST(10,20,5) as small_number;求最大值或者是最小值的时候要是存在null的话结果直接就是null不是我们需要的值。

求最大值或者是最小值的时候要是存在null的话结果直接就是null不是我们需要的值。
 

 3.2位运算符

主要是对二进制的相关的操作

-- =============================位相关操作===============================
-- 位与
SELECT 3 &5;
-- 0011
-- 0101
-- 结果:0001 全是1的时候才全是1-- 位或
-- 不是0就是1
SELECT 3 | 5;-- 右移位
SELECT 2>>1;-- 左移位
SELECT 2<<1;-- 位取反 
-- 1变0,0变1,变的很大的数的原因是2是32位的数字
SELECT ~2;

4.基本查询-排序

排序  

-- ===================================排序和分页====================================
-- 按照降价降序
-- 默认升序
SELECT * FROM product ORDER BY price;
SELECT * FROM product ORDER BY price ASC;
-- 降序
SELECT * FROM product ORDER BY price DESC;-- 价格降序 分配升序
SELECT * FROM product ORDER BY price DESC,category_id ASC;-- 查询所有的价格 去重
SELECT DISTINCT price FROM product ORDER BY price ASC;

5.基本查询-聚合操作

下面的操作是针对不同的列的相关的操作

 

count 行数
sum 数值和-- ==========================================聚合操作===================================-- 商品条数
-- * 不为空的行
SELECT COUNT(*) FROM product ;SELECT COUNT(pid) FROM product ;-- 价格大于5000的商品的总条数SELECT COUNT(pid) FROM product  WHERE price > 5000;-- 查询c001商品的总价格SELECT SUM(price) FROM product  WHERE category_id ='c001';-- 查询商品的最大价格SELECT Max(price) FROM product  ;-- 查询商品的最小价格SELECT Min(price) FROM product  ;-- 平均价格SELECT Avg(price) FROM product  ;-- 求某个类的平均价格SELECT Avg(price) FROM product  WHERE category_id ='c001';-- 求最大和最小价格SELECT Min(price),Max(price)  FROM product  ;

对null的操作

 

-- ==========================================聚合操作-对null的操作===================================
-- 创建测试表
DROP TABLE IF EXISTS test_null;
CREATE TABLE IF NOT EXISTS test_null(
c1 VARCHAR(20),
c2 int 
);
-- 创建测试数据
INSERT INTO test_null VALUES
('aaa',3),
('bbb',4),
('ccc',NULL),
(NULL,5);-- 测试
-- 要是选中的列是null的视而不见的,不进行统计
SELECT COUNT(*) ,COUNT(1) ,COUNT(c1),COUNT(c2)FROM test_null;-- 要是null的话,求平均值的时候就当作不存在的
SELECT max(c2) ,min(c2) ,avg(c2)FROM test_null;

6.聚合操作-分组查询

多了一个分组。可以一个或者是多个分组,可以采用having进行相关的分组的操作

必须商品中的类别就是一个分组的条件。

-- ==========================================聚合操作-分组查询===================================-- 统计 不同分类的商品
-- 相当于把相同类别的设置成了一张表,分别对其进行求和的操作
SELECT category_id,COUNT(*) FROM product GROUP BY category_id;SELECT category_id ,COUNT(1) FROM product GROUP BY category_id;

 下面是对分组过程的介绍。分组一般是和聚合是在一起进行使用的。

 

7.聚合操作-分组筛选

-- ==========================================聚合操作-分组筛选===================================
-- 统计每个类别的商品的数量并且将输出每个类别中商品数量大于5的类别的id和商品数量
SELECT category_id ,COUNT(1) FROM product GROUP BY category_id HAVING COUNT(1)>5 ;

下面是执行的顺序

 

可以加上对应的排序的字段
-- 加上排序
SELECT category_id ,COUNT(1) FROM product GROUP BY category_id HAVING COUNT(1)>5 ORDER BY category_id DESC ;

8.基本查询-分页查询

limit n:显示前n条

limit m,n:从m+1条开始显示n条


-- ==========================================基本查询-分页操作===================================
-- 显示前5条数据
SELECT * FROM product LIMIT 5;-- 从第4条开始显示5条
SELECT * FROM product LIMIT 3,5;-- 模拟分页
-- (当前页-1)*页大小
SELECT * FROM product LIMIT 0,5;SELECT * FROM product LIMIT 5,5;

9.将查询结果插入到新的表

将后面的结果插入到前面的表

  • 字段一致

  • 类型一致

  • 要插入的表必须先存在

-- ==========================================基本查询-插入新的表中===================================-- 创建测试的表
CREATE TABLE IF NOT EXISTS product2(
id int PRIMARY key ,
pname VARCHAR(20) ,
price DOUBLE
);-- 插入到上面的表
INSERT INTO product2(id,pname,price) SELECT pid,pname,price FROM product;

10.基本查询-总结

  • 简单查询:不加任何的条件。全表。字段和*。别名查询。列和表的别名。

  • 去重查询:distinct。去重重复的列或者重复的行。

  • 运算符:算数,比较,逻辑和位。

默认的是升序asc。

特点:如果order by后面跟一个字段,只会按照该字段的值进行排序。其他的字符是没有排序的。

聚合查询操作:

count(1)等价于count(*)

注意有null的值就不进行相关的操作,

分组操作:

  • 将一个表拆分成多个表

  • 分组的时候可以根据多个字段进行分组。字段相同的分到一个组,多个字段相同也是可以分到一个组中。

  • 分完组之后后面只能跟分组字段和聚合操作

  • 一般情况下聚合函数和分组函数聚合在一起使用

  • 后续的操作必须采用having进行相关的聚合的操作

分页字段:limit

书写顺序:

select 字段 from 表
where 条件
group by 分组
having 筛选(必须根据分组的条件)
order by 排序字段
limit 分页

执行顺序

from 从哪个表中进行查询
where 筛选查询的结果group by 分组统计
count 执行聚合操作
having 筛选聚合的东西
select 进行查询
order by 排序limit 进行筛选

11.中级查询-sql中级操作

-- =================================中级查询=====================
-- 创建测试数据
DROP TABLE IF  EXISTS student;
CREATE TABLE  IF NOT EXISTS student(
id INT,
name VARCHAR(20),
gender VARCHAR(20),
chinese INT,
english INT,
math INT
);INSERT INTO student(id,name,gender,chinese,english,math) VALUES(1,'张三','男',89,79,70);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(2,'李四','女',89,99,80);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(3,'王五','男',79,69,90);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(4,'赵六','女',89,79,40);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(5,'陈二','男',99,89,50);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(6,'王瓜','女',49,99,60);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(7,'轧盖','男',59,89,70);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(8,'赵恒','女',69,49,80);
INSERT INTO student(id,name,gender,chinese,english,math) VALUES(8,'赵恒','女',69,49,80);-- 查询所有的数据SELECT * FROM student;-- 查询表中所有的学生的姓名和对应的英语成绩SELECT name,english FROM student ;-- 去重SELECT DISTINCT * FROM student ;-- 统计学生的总分SELECT  DISTINCT FROM student  ;-- 先进行去重了然后对不同学生的进行求总分-- 分组的时候必须进行起别名SELECT name, sum(chinese + english + math)  AS total FROM 
(SELECT * FROM student ) tmp GROUP BY name-- 对上面的总分加上10SELECT name, sum(chinese + english + math + 10)  AS total FROM 
(SELECT * FROM student ) tmp GROUP BY name-- 找出英语大于90分的SELECT  * FROM student WHERE english>90;-- 查出总分大于200的-- 聚合操作的求和SELECT name,sum(chinese + english + math ) total  FROM  (SELECT DISTINCT  * FROM student ) tmp GROUP BY name HAVING total > 200;-- 非聚合操作的求和-- 此时不能用前面的别名但是having是可以。原因是执行顺序的原因SELECT  DISTINCT name,(chinese + english + math) total   FROM student WHERE (chinese + english + math)>200;-- 找出英语在80-90之间的SELECT  * FROM student WHERE english >=80 and english <=90;SELECT  * FROM student WHERE english BETWEEN 80 AND 90;-- 找出英语不在80-90之间的SELECT  * FROM student WHERE english NOT  BETWEEN 80 AND 90;SELECT  * FROM student WHERE NOT (english   BETWEEN 80 AND 90);SELECT  * FROM student WHERE NOT (english >=80 and english <=90);SELECT  * FROM student WHERE  english <80 OR english >90;-- 查询数学是70和50的同学SELECT  * FROM student WHERE math  =  70 OR math  =50;SELECT  * FROM student WHERE math  =  IN (70,50);-- 查询数学是不是70或50的同学SELECT  * FROM student WHERE math  != 70 AND math  !=50;SELECT  * FROM student WHERE math   NOT IN (70,50);-- 查询所有姓王的英语成绩SELECT  name,english  FROM student WHERE  name LIKE '%王';-- 查询总分是238并且姓张的同学的信息SELECT * FROM student WHERE name like '张%' AND (chinese + english + math)=238;-- 按照分数从高到低的顺序查询并显示出来SELECT id,name,SUM(english+chinese+math) AS count ,gender FROM (SELECT DISTINCT * FROM student)  s GROUP BY id  ORDER BY count;-- 按照性别进行查询并统计男和女的顺序,根据性别进行降序输出SELECT gender,COUNT(gender) AS count FROM student GROUP BY gender HAVING count >=5 ORDER BY count;

12.正则表达式

定义了一些相关的字符串的匹配的规则,本身是一个字符串,回匹配一些列符合某个句法的规则的字符串。常常用于检索,替换那些符合规则恶的文本,

可以采用regexp关键字支持正则表达式

^ 匹配输入字符串开始位置
$ 匹配输入字符串结束位置
. 匹配除了\n之外的任何单个字符
[...] 字符集合,包含的任意一个字符。[abc]可以匹配 plain中的a
[^...]负值字符集合。匹配未包含的任意字符
p1|p2|p3 匹配p1 p2或者 p3
* 0次或者多次
+ 匹配前面子表达式一次或者多次
{n} 
{n,m}

下面是演示在项目中的基本的使用

 -- ====================正则表达式-- 判断字符串是不是以a开头SELECT 'abc' REGEXP '^a';-- $判断以某个字符结尾的SELECT 'abc' REGEXP 'a$';SELECT 'abc' REGEXP 'c$';

下面是常见的正则匹配

 -- ======================下面是真正的项目中的使用-- 找以苹开始的所有的信息SELECT * FROM product WHERE pname REGEXP '^苹';-- 找以国结尾的数据SELECT * FROM product WHERE pname REGEXP '国$';-- .可以匹配任意单个字符SELECT 'abc' REGEXP '.a';-- 0SELECT 'abc' REGEXP '.b';-- 1SELECT 'abc' REGEXP '.c'; -- 1-- [...]匹配括号内的任意单个字符SELECT 'abc' REGEXP '[ade]'-- 1SELECT 'abc' REGEXP '[xyz]'-- 0-- [^..]匹配括号内的任意单个字符SELECT 'a' REGEXP '[^ade]'; -- 0SELECT 'abc' REGEXP '[^ade]'; -- 1SELECT 'abc' REGEXP '[^xyz]'; -- 1-- * 匹配0到多个字符SELECT 'stab' REGEXP '.ta*b'; -- 1SELECT 'stb' REGEXP 'ta*b'; -- -- a+ 字符a出现一次或者多次SELECT 'stab' REGEXP '.ta+b'; -- 1SELECT 'stb' REGEXP 'ta+b'; -- 0-- a? 匹配0个或者1个字符SELECT 'abc' REGEXP 'a?'SELECT 'bc' REGEXP 'a?'-- a1 |a2匹配a1或者a2SELECT 'a' REGEXP 'a|b';SELECT 'c' REGEXP 'a|b';

下面是剩下的常见的正则匹配的规则

-- 以a或者b开头的SELECT 'abc' REGEXP '^(a|b)';SELECT 'cd' REGEXP '^(a|b)';-- a{m} 匹配m个aSELECT 'aaab' REGEXP 'a{4}'; -- 0-- a{m,} 至少出现m次SELECT 'aaaa' REGEXP 'a{3}';-- 1SELECT 'aaaa' REGEXP 'a{5}';-- 0-- a{m,n} 至多n,至少出现m次SELECT 'aaaa' REGEXP 'a{4,5}';-- 1--  (ab)必须以ab整体匹配SELECT 'abc' REGEXP '(ab)';-- 1SELECT 'abc' REGEXP '(ab){2,}';-- 0

13.多表操作

表关系就是表与之间的关系

1v1的关系

  • 一个学生对应一个身份证一个身份证对应一个学生

  • 在一个表中就行不用分成两个表

1v多

  • 部门和员工:一个部门有多个员工,一个员工只能对应一个部门

  • 外键在多端的一方

 

多对多

  • 学生和课程之间就是多对多的关系

  • 演员和角色之间的关系

  • 中间表的形式进行表示

外键约束

  • 表的特殊的字段和主键一起配合进行使用

  • 外键关联的表是从表。也就是说有外键的表是从表,没有外键的表是主表。

  • 员工和部门之间的关系就是员工表是从表,部门表是主表。

  • 我们可以把表的类型分为主表和从表。

 

主表必须存在。必须是主键。不能包含空的值。可以采用复合的外键。外键中的列数必须和主键中的列数是一致的

14.外键约束

14.1外键约束的基本操作

创建表的时候可以指定外键约束。

在创建表的时候可以采用foreign key 去指定外键。

 -- 创建部门表DROP TABLE IF EXISTS dept;CREATE TABLE IF not EXISTS dept(deptno VARCHAR(20) PRIMARY key,name VARCHAR(20));DROP TABLE IF EXISTS emp;CREATE TABLE IF NOT EXISTS emp(eid VARCHAR(20) PRIMARY KEY,ename VARCHAR(20) ,age int,dept_id VARCHAR(20) ,CONSTRAINT fk FOREIGN KEY (dept_id) REFERENCES dept(deptno));

 创建完表再去添加表的约束

 -- 创建部门表DROP TABLE IF EXISTS dept2;CREATE TABLE IF not EXISTS dept2(deptno VARCHAR(20) PRIMARY key,name VARCHAR(20));DROP TABLE IF EXISTS emp2;CREATE TABLE IF NOT EXISTS emp2(eid VARCHAR(20) PRIMARY KEY,ename VARCHAR(20) ,age int,dept_id VARCHAR(20) 
--  CONSTRAINT fk FOREIGN KEY (dept_id) REFERENCES dept(deptno)
--  );ALTER TABLE emp2 ADD CONSTRAINT fk2 FOREIGN KEY (dept_id) REFERENCES dept2(deptno);

14.2外键约束的数据

必须先给部门表进行数据插入

 -- 给主表添加数据insert into dept VALUES
('1001','研发部'),
('1002','销售部'),
('1003','财务部'),
('1004','人事部');

然后给从表添加数据

 -- 给从表添加数据insert into emp VALUES
('1','张三',20,'1001'),
('2','张三',20,'1002'),
('3','张三',20,'1003'),
('4','张三',20,'1004');

测试外键约束

  • 失败:存在重复

  • 成功:可以插入外键可以指定为null

 -- 测试外键约束insert into emp VALUES ('1','张三',20,'1005');
-- null是可以的insert into emp VALUES ('1','张三',20,NULL);

删除测试

--dept数据 删除DELETE FROM dept WHERE deptno='1002';删除是拒绝的
从表的数据是可以随便删除的,删除的时候需要注意

14.3删除外键约束

采用修改表的方式进行删除

 ALTER TABLE 表名 DROP FOREIGN key  外键约束名称;ALTER TABLE emp2 DROP FOREIGN key  fk2;

14.4多对多外键约束

相互之间的约束

采用中间表的形式。除了中间表都是主表。

DROP TABLE IF EXISTS stu;CREATE TABLE IF not EXISTS stu(stu_id VARCHAR(20) PRIMARY key,stu_name VARCHAR(20));DROP TABLE IF EXISTS score;CREATE TABLE IF not EXISTS score(score_id VARCHAR(20) PRIMARY key,score_name VARCHAR(20));DROP TABLE IF EXISTS stu_score;CREATE TABLE IF not EXISTS stu_score(stu_id VARCHAR(20),score_id VARCHAR(20),score DOUBLE, -- 课程成绩PRIMARY key (stu_id,score_id));ALTER TABLE stu_score ADD CONSTRAINT FOREIGN KEY (stu_id) REFERENCES stu(stu_id);ALTER TABLE stu_score ADD CONSTRAINT FOREIGN KEY (score_id) REFERENCES score(score_id);

查看表模型

 

删除表的时候必须先删除从表。添加数据的时候先给主表添加数据

删除数据的时候先删除从表中的数据再去删除主表中的数据。

此时数据就像是添加了对应的字典的限制似的,不能直接进行删除的操作。

 

 

15.多表联合查询

15.1常见的联合查询的类型

下面是常见的连接查询的操作.

 

  • 直接查询就是笛卡尔积

  • 内连接

  • 左外

  • 右外

  • 满外连接

创建基本的表和测试的数据

-- ============================多表查询-数据准备=============
-- 创建部门表
create table if not exists dept3(deptno varchar(20) primary key ,  -- 部门号name varchar(20) -- 部门名字
);-- 创建员工表
create table if not exists emp3(eid varchar(20) primary key , -- 员工编号ename varchar(20), -- 员工名字age int,  -- 员工年龄dept_id varchar(20)  -- 员工所属部门
);-- 给dept3表添加数据
insert into dept3 values('1001','研发部');
insert into dept3 values('1002','销售部');
insert into dept3 values('1003','财务部');
insert into dept3 values('1004','人事部');-- 给emp3表添加数据
insert into emp3 values('1','乔峰',20, '1001');
insert into emp3 values('2','段誉',21, '1001');
insert into emp3 values('3','虚竹',23, '1001');
insert into emp3 values('4','阿紫',18, '1001');
insert into emp3 values('5','扫地僧',85, '1002');
insert into emp3 values('6','李秋水',33, '1002');
insert into emp3 values('7','鸠摩智',50, '1002'); 
insert into emp3 values('8','天山童姥',60, '1003');
insert into emp3 values('9','慕容博',58, '1003');
insert into emp3 values('10','丁春秋',71, '1005');

15.2不加连接条件的查询

直接形成一个笛卡尔积,两个表中的数据进行相乘

a表的每一行和b表的每一行进行匹配。

冗余的数据非常多

 

行数=部门行数*员工行数

列数=部门列数+员工行数

-- ======交叉查询
SELECT * FROM dept3,emp3;

15.3内连接查询

交集查询

-- 采用999标准写
-- ====内连接查询
SELECT * from  dept3   INNER JOIN emp3 on dept3.deptno=emp3.dept_id;-- 等价于下面的效果 
-- inner可以默认不写效果是一样的
SELECT * from  dept3    JOIN emp3 on dept3.deptno=emp3.dept_id;

上面查询的哪个部门有哪些员工,就是采用的内连接的形式。

-- 查询研发部门的员工
SELECT * from  dept3 d JOIN emp3 e on d.deptno=e.dept_id where d.name ='研发部';-- 查询研发部和销售部的所属员工
select * from dept3 a join emp3 b on a.deptno = b.dept_id and (name = '研发部' or name = '销售部') ; 
select * from dept3 a join emp3 b on a.deptno = b.dept_id and name in('研发部' ,'销售部') ; -- 查询每个部门的员工数,并升序排序
select a.*,COUNT(*) as total from dept3 a join emp3 b on a.deptno = b.dept_id  GROUP BY a.deptno ; -- 查询人数大于等于3的部门,并按照人数降序排序
select a.*,COUNT(*) as total from dept3 a join emp3 b on a.deptno = b.dept_id  GROUP BY a.deptno HAVING total>3 ORDER BY total DESC; 

15.4外连接查询

左外和右外和全连接

oracle中是有full join的但是在MySQL中是没有的需要采用union进行连接的。

-- =================外连接查询
-- 查询哪些部门有员工,哪些部门没有员工
-- 本质就是查询所有部门的员工
SELECT * FROM dept3 d LEFT JOIN emp3 e on  d.deptno=e.dept_id;-- 查询哪些员工有部门,哪些员工没有部门
SELECT * FROM dept3 d RIGHT JOIN emp3 e on  d.deptno=e.dept_id;-- 合并查询的结果
SELECT * FROM dept3 d LEFT JOIN emp3 e on  d.deptno=e.dept_id
UNION
SELECT * FROM dept3 d RIGHT JOIN emp3 e on  d.deptno=e.dept_id;

15.5多表联合查询

多表联合查询

select from where c> all查询语句等价于下面的语句
select from where c> result1 and  c> result2 and c> result3 也就是c大于所有的子查询得结果

特点:

  • 与子查询中所有得结果比较才是true,否则是false

  • all可以和=,>等进行结合使用。表示大于所有得,表示等于所有得值,表示大于等于所有得值。

-- ================多表联合查询================
-- 子查询关键字-- 查询年龄大于1003部门中所有年龄员工得信息
SELECT * FROM  emp3  WHERE age > all(SELECT age FROM emp3 WHERE  dept_id='1003');
-- 查询不属于任何一个部门得员工信息
SELECT * FROM  emp3  WHERE dept_id != all(SELECT deptno FROM dept3 );

下面是any和some

  • any:只要比其中一个值大于,小于等就行。不需要比较所有得值。只需要比较部分得值。

  • some:和any得作用是一致得。可以理解为any得别名。

-- 查询年龄大于1003部门中任意一个员工员工得信息
SELECT * FROM  emp3  WHERE age > ANY(SELECT age FROM emp3 WHERE  dept_id='1003' ) and dept_id !='1003';SELECT * FROM  emp3  WHERE age > SOME(SELECT age FROM emp3 WHERE  dept_id='1003' ) and dept_id !='1003';

 15.6自关联查询

自己关联自己,就是隐式自连接得操作。可以采用内连接得操作。一张表当作多张表进行使用。

CREATE TABLE `t_sanguo` (`eid` int(11) NOT NULL AUTO_INCREMENT,`ename` varchar(30) DEFAULT NULL,`manager_id` int(11) DEFAULT NULL,PRIMARY KEY (`eid`),KEY `manager_id` (`manager_id`),CONSTRAINT `t_sanguo_ibfk_1` FOREIGN KEY (`manager_id`) REFERENCES `t_sanguo` (`eid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (1, '刘协', NULL);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (2, '刘备', 1);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (3, '关羽', 2);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (4, '张飞', 2);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (5, '曹操', 1);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (6, '许诸', 5);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (7, '孙权', 1);
INSERT INTO `sys_test`.`t_sanguo` (`eid`, `ename`, `manager_id`) VALUES (8, '周瑜', 7);
-- ===================================自关联查询===================
SELECT * FROM t_sanguo;-- 查询每一个人物得信息并且包含领导得信息
-- 就是左表得manager_id等于右表的eid
SELECT t1.*,t2.eid '领导编号' , t2.ename '领导名称' FROM t_sanguo t1 LEFT JOIN  t_sanguo t2 ON t1.manager_id=t2.eid;-- 擦汗寻所有人物和上级和上上级
SELECT t.eid,t.ename ,temp.eid '上级领导编号' ,temp.ename '上级领导名',temp.`领导编号`,temp.`领导名称`   FROM t_sanguo t LEFT JOIN (
SELECT t1.*,t2.eid '领导编号' , t2.ename '领导名称' FROM t_sanguo t1 LEFT JOIN  t_sanguo t2 ON t1.manager_id=t2.eid
) temp  ON t.manager_id=temp.eid-- 下面是采用自关联三张表的操作进行的查询的操作将自己作为三张独立的表进行的关联的查询的操作
SELECT 
t1.eid  ,t1.ename ,
t2.eid '上级领导编号' ,t2.ename '上级领导姓名',
t3.eid  '上上级领导编号',t3.ename  '上上级领导姓名'
FROM t_sanguo t1
LEFT JOIN t_sanguo t2  on t1.manager_id =t2.eid
LEFT JOIN t_sanguo t3 on t2.manager_id =t3.eid

15.7多表查询总结

外键约束

  • 主表

  • 从表

外键约束的创建的方式

  • 直接在后面加上外键

  • 采用修改表的方式进行创建外键约束

特点:

  • 主表的数据可以随便加,不能随便删除

  • 从表的数据可随便删除,不能随便添加

连接查询

  • 内:join就是。两张表的交集。

  • 外:左外和右外。

  • 全:union可以合并左外和右外的连接的查询的结果

  • 交叉:不用,笛卡尔积

自查询:

  • select的嵌套查询

  • 子查询的结果作为一个值 = 的操作,多个值 in的操作。当作一个表,可以进行表的连接的查询的操作

关键字

  • all:全部满足

  • any和some只是有一个满足就是可以的

  • exists:如果查询的有结果就是可以的,否则就是false

自关联:

  • 表必须起别名

16.子查询

嵌套多个具有子查询的小查询。返回的中间结果存在多种。

单行单列

单行多列

多行多列

多行多列


-- =================子查询
-- 查询年龄最大的员工的信息。包含员工全部信息
-- 单行单列可以直接采用=
SELECT MAX(age) FROM emp3;
SELECT * FROM emp3 WHERE age=(SELECT MAX(age) FROM emp3);
SELECT * FROM emp3 WHERE age in (SELECT MAX(age) FROM emp3);-- 查询研发部和销售部的员工的信息
SELECT * FROM emp3 WHERE dept_id in (SELECT deptno   FROM dept WHERE name in ('研发部','销售部') );SELECT * FROM emp3  e INNER JOIN dept d on e.dept_id=d.deptno;

 下面展示的是多表查询,设置了连个子查询然后进行了表连接。

 

17.IN关键字

只要是任意一个符合就是可以得。等价于得语句就是or

select from where c=result1 or c=result2 or c=result3-- 查询研发部和销售部员工的信息
SELECT * FROM emp3 WHERE dept_id IN (SELECT deptno FROM dept3 WHERE name='研发部' or name ='销售部');

18.exists关键字

和IN关键字是差不多的

其实就是给出一个让where查询条件成立的一个表达式语句

 

select  from where exists 查询语句

  • 返回至少存在一行数据得话就是可以 得返回得是true要是不成立得话就是不成立得。

  • exists后面得子查询中不反悔任何得数据。只能返回真和假,就是给where进行成立得。

-- 下面会进行全表得输出
SELECT * FROM emp3 WHERE EXISTS (SELECT * FROM emp3) -- 查询公司大于60岁得员工
SELECT * FROM emp3 WHERE age >60;
-- 下面就是采用exists进行得操作
SELECT * FROM emp3  e WHERE EXISTS ( SELECT * FROM emp3 WHERE e.age>60);-- 查询有所属部门得员工的信息
SELECT * FROM emp3  e WHERE EXISTS (SELECT *  FROM dept3 d  WHERE e.dept_id =d.deptno);-- 查询没有所属部门得员工的信息
SELECT * FROM emp3  e WHERE not EXISTS (SELECT *  FROM dept3 d  WHERE e.dept_id =d.deptno);

exists的查询的效率是比较高得。

19.MySQL常见的函数

别人写好的模板代码。

聚合函数

数学函数

日期函数

控制流函数

窗口函数

19.1聚合函数

前面学的就是count,sum。ave和max,min

现在有一个group_

--  创建一个新的表
CREATE TABLE `emp4` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`salary` decimal(10,2) DEFAULT NULL,`dept_id` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;-- 准备下面的测试数据
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (1, '张三', 1200.00, '人事部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (2, '李四', 1500.00, '财务部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (3, '王五', 1600.00, '财务部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (4, '赵六', 1700.00, '人事部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (5, '陈二', 1500.00, '销售部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (6, '张伞', 1600.00, '销售部');
INSERT INTO `sys_test`.`emp4` (`id`, `name`, `salary`, `dept_id`) VALUES (7, '招录', 1700.00, '销售部');

将所有的员工的名字合成一行

-- 聚合操作
-- 将所有的员工的名字合成一行-- 默认的是逗号分隔符
SELECT GROUP_CONCAT(name) FROM emp4;-- 指定分隔符
SELECT GROUP_CONCAT(name SEPARATOR '-') FROM emp4;-- 指定分组的方式
SELECT dept_id, GROUP_CONCAT(name SEPARATOR '-') FROM emp4 group by dept_id;-- 指定排序的规则
SELECT dept_id, GROUP_CONCAT(name ORDER BY salary SEPARATOR '-') FROM emp4 group by dept_id;

先按照部门的名称进行分组然后再进行拼接的操作

 

下面是指定排序表的规则的操作

 

19.2数学函数

-- ==============================数学函数=========================
-- 绝对值
SELECT ABS(-10);-- 往上取整 结果是2
SELECT CEIL(1.1);-- 往下取整 结果是1
SELECT floor(1.1);-- 返回列表的最大值
SELECT GREATEST(1,2,3);-- 返回列表的最小值
SELECT least(1,2,3);-- mod 取余数
SELECT MOD(5,2)-- INDEX
SELECT POWER(5,2)-- 随机数
-- 0-1之间
SELECT RAND();-- 返回0-100之间的
SELECT RAND()*100;-- 四舍五入
SELECT ROUND(3.56);
SELECT ROUND(3.46);-- 保留小数位数
SELECT ROUND(3.46,1);-- 直接取几位不四舍五入
SELECT TRUNCATE (3.1415926,3);

19.3字符串函数

-- ===========================字符串函数=======================
-- 返回字符串字符个数
SELECT char_length('hello') ;-- 注意一个汉字是一个字符
SELECT char_length('你好啊') ;-- length根据的是字节进行的计算
SELECT length('hello') ;-- 一个汉字3个字节。采用的是utf8编码导致的
SELECT length('你好啊') ;-- 字符串合并 没有分隔符
SELECT CONCAT('你好','啊')--  字符串合并 有分隔符,第一个就是就是分隔符
SELECT CONCAT_WS('-','你好','啊')-- 返回字符串在列表中的位置 第一次出现的位置
-- 你好在后面字符中出现的位置 1
SELECT  FIELD('你好','你好','啊','张伞')
-- 位置2
SELECT  FIELD('啊','你好','啊','张伞')-- 去除左边的空格
SELECT '   你好';
SELECT LTRIM('   你好');-- 去除右边的空格
SELECT RTRIM('你好     ')-- 去除两侧的空格
SELECT trim('   你好     ')-- 从字符串s中截取
-- 从第2个字符开始,截取的长度为3。从1开始的。
-- 结果:ell
SELECT MID('helloworld',2,3)-- 判断一个字符串在另外一个字符串中出现的位置
-- 从1开始的
SELECT POSITION('wo' in 'helloworld')-- 字符串替换
-- 替换的是所有符合规则的
SELECT REPLACE('helloworld','hello' ,'你好');-- 字符串反转
SELECT REVERSE('helloworld');-- ===========================字符串函数=======================
-- 返回字符串后几个字符 llo
SELECT RIGHT('hello',3);-- 比较两个字符串的大小
-- -1表示小于,挨个字符进行比较的,按照的是字典的顺序
SELECT STRCMP('hello','hi');-- 字符串截取
-- ell从第2个字符开始截取3个字符 ell
SELECT SUBSTR('hello' ,2 ,3);
SELECT SUBSTring('hello' ,2 ,3);-- 小写变大写
SELECT ucase('hello' );
SELECT upper('hello' );-- 大写变小写SELECT lcase('HELLO' );
SELECT LOWER('HELLO' );

19.4日期相关函数

-- ====================下面是日期相关的函数=================
-- 返回毫秒值 获取时间戳 从1970年开始的
SELECT UNIX_TIMESTAMP();-- 将日期字符串转换成毫秒值
SELECT UNIX_TIMESTAMP('2023-08-18 08:47:05');-- 将毫秒值转换成指定格式的日期
-- 必须按照指定的格式
SELECT FROM_UNIXTIME(1692319625,'%Y-%m-%d %H:%i:%s')

格式化日期的时候必须按照下面的格式进行编写

 

- 获取当前的日期
-- 2023-08-18
SELECT CURDATE();
SELECT CURRENT_DATE();-- 获取当前时分秒
-- 08:51:39
SELECT CURRENT_TIME();
SELECT CURTIME();-- 获取完整的日期
-- 2023-08-18 08:52:04
SELECT CURRENT_TIMESTAMP();-- 从日期字符串中获取年月日
-- 需要符合日期的规范 2023-08-18
SELECT DATE('2023-08-18 08:52:04')-- 日期之间的差值 31
SELECT DATEDIFF('2023-08-18','2023-07-18')

下面是可以加减的日期的参数

 

-- 时间之间的插值。查了多少秒 00:01:00
SELECT TIMEDIFF('08:52:04','08:51:04');-- 日期按照指定的格式化 2023-08-18 08:52:04
-- 能够保证转换出来的日期的长度是一样的
SELECT DATE_FORMAT('2023-8-18 8:52:4','%Y-%m-%d %H:%i:%s')-- 字符串换日期 2023-08-18 08:52:04
SELECT STR_TO_DATE('2023-8-18 8:52:4','%Y-%m-%d %H:%i:%s')-- STR_TO_DATE可以把英文的时间也转换出来-- 日期进行减法 日期减去2天
SELECT DATE_SUB('2023-08-18 08:52:04',INTERVAL 2 DAY)-- 日期加法 2023-08-20 08:52:04
SELECT DATE_ADD('2023-08-18 08:52:04',INTERVAL 2 DAY)
SELECT ADDDate('2023-08-18 08:52:04',INTERVAL 2 DAY)-- 从日期中获取时间
SELECT EXTRACT(HOUR FROM '2023-08-18 08:52:04')SELECT EXTRACT(YEAR FROM '2023-08-18 08:52:04')SELECT EXTRACT(MONTH FROM '2023-08-18 08:52:04')-- 获取最后一天 2023-08-31
SELECT LAST_DAY('2023-08-18 08:52:04')-- 获取指定年的哪一天是几号
SELECT MAKEDATE('2023',8);-- 获取年
SELECT YEAR('2023-08-18 08:52:04');-- 获取月
SELECT MONTH('2023-08-18 08:52:04');-- 天
SELECT SECOND('2023-08-18 08:52:04');-- 小时
SELECT HOUR('2023-08-18 08:52:04');-- 分钟
SELECT MINUTE('2023-08-18 08:52:04');-- 秒
SELECT SECOND('2023-08-18 08:52:04');-- 获取季度 1-4
SELECT QUARTER('2023-08-18 08:52:04');-- 月的名字 August
SELECT MONTHNAME('2023-08-18 08:52:04');-- 天的名字
SELECT DAYNAME('2023-08-18 08:52:04');-- 这个月中第几天 18
SELECT DAYOFMONTH('2023-08-18 08:52:04');-- 周中第几天 6
SELECT DAYOFWeek('2023-08-18 08:52:04');-- 年中多少天 230
SELECT DAYOFYear('2023-08-18 08:52:04');-- 本年的第几个周 33
SELECT WEEK('2023-08-18 08:52:04');
-- 1
SELECT WEEK('2023-01-01 00:00:00');-- 今天是周几 4+1
SELECT WEEKDAY('2023-08-18 08:52:04');-- 本年第几个星期
SELECT WEEKOFYEAR('2023-08-18 08:52:04');-- 年份及第几周 202333
SELECT YEARWEEK('2023-08-18 08:52:04');-- 当前的时间
SELECT NOW();

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/45233.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一文详解4种聚类算法及可视化(Python)

在这篇文章中&#xff0c;基于20家公司的股票价格时间序列数据。根据股票价格之间的相关性&#xff0c;看一下对这些公司进行聚类的四种不同方式。 苹果&#xff08;AAPL&#xff09;&#xff0c;亚马逊&#xff08;AMZN&#xff09;&#xff0c;Facebook&#xff08;META&…

计算机毕设项目之基于django+mysql的疫情实时监控大屏系统(前后全分离)

系统阐述的是一款新冠肺炎疫情实时监控系统的设计与实现&#xff0c;对于Python、B/S结构、MySql进行了较为深入的学习与应用。主要针对系统的设计&#xff0c;描述&#xff0c;实现和分析与测试方面来表明开发的过程。开发中使用了 django框架和MySql数据库技术搭建系统的整体…

多线程实现与管理

进程与线程 进程 &#xff1a; 进程是操作系统进行资源分配的最小单位&#xff0c;每执行一个程序、一条命令操作系统都会启动一个进程&#xff0c;进程是一个程序的执行过程&#xff0c;当程序启动时&#xff0c;操作系统会把进程的代码加载到内存中&#xff0c;并为新进程分配…

uni-app根据经纬度逆解析详细地址

uni-app中的getLocation()方法可以获取到用户当前的地理位置&#xff08;经纬度&#xff09;、速度。 但是返回参数中的address在app中才会显示&#xff0c;小程序中不会显示&#xff0c;所以我们需要进行逆解析其地址&#xff0c;解析出它的地址信息。 1.首先要在腾讯位置服务…

如何正确地设置Outlook SMTP发送电子邮件(wordpress配置)

如何正确地设置Outlook SMTP发送电子邮件&#xff08;wordpress配置&#xff09; 作者&#xff1a;虚坏叔叔 博客&#xff1a;https://pay.xuhss.com 早餐店不会开到晚上&#xff0c;想吃的人早就来了&#xff01;&#x1f604; 正在寻找正确的Outlook SMTP设置&#xff1f…

LRU 算法

LRU 缓存淘汰算法就是一种常用策略。LRU 的全称是 Least Recently Used&#xff0c;也就是说我们认为最近使用过的数据应该是是「有用的」&#xff0c;很久都没用过的数据应该是无用的&#xff0c;内存满了就优先删那些很久没用过的数据。 力扣&#xff08;LeetCode&#xff09…

自动方向识别式 TXB型电平转换芯片

大家好,这里是大话硬件。 在上一篇文章分析了LSF型的电平转换芯片,LSF型电平转换芯片最常见是应用在I2C总线上。I2C为OD型总线,LSF使用时增加电阻。 对于不是OD型总线的电平转换,比如UART,SPI,普通GPIO口信号,这些信号在进行双向电平转换使用什么样的芯片呢? 从上面…

面试之快速学习STL-deuqe和list

1. deque deque 容器用数组&#xff08;数组名假设为 map&#xff09;存储着各个连续空间的首地址。也就是说&#xff0c;map 数组中存储的都是指针如果 map 数组满了怎么办&#xff1f;很简单&#xff0c;再申请一块更大的连续空间供 map 数组使用&#xff0c;将原有数据&…

每天一道leetcode:433. 最小基因变化(图论中等广度优先遍历)

今日份题目&#xff1a; 基因序列可以表示为一条由 8 个字符组成的字符串&#xff0c;其中每个字符都是 A、C、G 和 T 之一。 假设我们需要调查从基因序列 start 变为 end 所发生的基因变化。一次基因变化就意味着这个基因序列中的一个字符发生了变化。 例如&#xff0c;&quo…

博弈论 | 斐波那契博弈

斐波那契博弈 博弈论是二人或多人在平等的对局中各自利用对方的策略变换自己的对抗策略,达到取胜目标的理论。博弈论是研究互动决策的理论。博弈可以分析自己与对手的利弊关系,从而确立自己在博弈中的优势,因此有不少博弈理论,可以帮助对弈者分析局势,从而采取相应策略,最终达…

计算机提示mfc120u.dll缺失(找不到)怎么解决

在计算机领域&#xff0c;mfc120u.dll是一个重要的动态链接库文件。它包含了Microsoft Foundation Class (MFC) 库的特定版本&#xff0c;用于支持Windows操作系统中的应用程序开发。修复mfc120u.dll可能涉及到解决与该库相关的问题或错误。这可能包括程序崩溃、运行时错误或其…

13.实现业务功能--板块信息

目录 获取在首页中显示的版块 1. 实现逻辑 2. 创建扩展 Mapper.xml 3. 修改 DAO 4. 创建 Service 接口 5. 实现 Service 接口 6. 生成测试方法 7. 实现 Controller 8. 实现前端页面 在数据库中执行以下 SQL 语句&#xff1a; INSERT INTO t_board (id, name, article…

浅析Linux SCSI子系统:调试方法

文章目录 SCSI日志调试功能scsi_logging_level调整SCSI日志等级 SCSI trace events使能SCSI trace events方式一&#xff1a;通过set_event接口方式二&#xff1a;通过enable 跟踪trace信息 相关参考 SCSI日志调试功能 SCSI子系统支持内核选项CONFIG_SCSI_LOGGING配置日志调试…

kafka晋升之路-理论+场景

kafka晋升之路 一&#xff1a;故事背景二&#xff1a;核心概念2.1 系统架构2.2 生产者&#xff08;Producer&#xff09;2.2.1 生产者分区2.2.2 生产者分区策略 2.3 经纪人&#xff08;Broker&#xff09;2.3.1 主题&#xff08;Topic&#xff09;2.3.2 分区&#xff08;Partit…

WPS-RCE

版本&#xff1a; WPS Office 2023 个人版 < 11.1.0.12313 WPS Office 2019 企业版 < 11.8.2.12085 原理&#xff1a; Office 中的 WebExtension&#xff08;通常称为 Office 插件或 Office 应用程序&#xff09;是一种用于扩展 Microsoft Office 功能的技术。Office …

回归预测 | MATLAB实现CSO-SVM布谷鸟优化算法优化支持向量机多输入单输出回归预测(多指标,多图)

回归预测 | MATLAB实现CSO-SVM布谷鸟优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09; 目录 回归预测 | MATLAB实现CSO-SVM布谷鸟优化算法优化支持向量机多输入单输出回归预测&#xff08;多指标&#xff0c;多图&#xff09;效果一…

FPGA应用学习笔记-----布线布局优化

优化约束&#xff1a; 设置到最坏情况下会过多 布局和布线之间的关系&#xff1a; 最重要的是与处理器努力的&#xff0c;挂钩允许设计者调整处理器努力的程度 逻辑复制&#xff1a; 不能放置多个负载&#xff0c;只使用在关键路径钟 减少布线延时&#xff0c;但会增加面积&a…

阿里云故障洞察提效 50%,全栈可观测建设有哪些技术要点?

本文根据作者在「TakinTalks 稳定性社区 」公开分享整理而成 #一分钟精华速览# 全栈可观测是一种更全面、更综合和更深入的观测能力&#xff0c;能协助全面了解和监测系统的各个层面和组件&#xff0c;它不仅仅是一个技术上的概念&#xff0c;更多地是技术与业务的结合。在“…

SpringBoot + MyBatis-Plus构建树形结构的几种方式

1. 树形结构 树形结构&#xff0c;是指&#xff1a;数据元素之间的关系像一颗树的数据结构。由树根延伸出多个树杈 它具有以下特点&#xff1a; 每个节点都只有有限个子节点或无子节点&#xff1b;没有父节点的节点称为根节点&#xff1b;每一个非根节点有且只有一个父节点&a…

整理mongodb文档:批量操作

个人博客 整理mongodb文档:批量操作 个人公众号&#xff0c;求关注&#xff0c;文章如有不明&#xff0c;请指出。 文章概叙 本文讲的是关于bulkwrite的用法&#xff0c;依旧是在shell下使用。 关于批量操作 Performs multiple write operations with controls for order …