时间:2021-07-01 10:21:17 帮助过:10人阅读
目录
# 插入完整数据(顺序插入)
语法一:
insert into 表名(字段1,字段2,字段3…字段n) values(值1,值2,值3…值n);
语法二:
insert into 表名 values (值1,值2,值3…值n);
# 指定字段插入数据
语法:
insert into 表名(字段1,字段2,字段3…) values (值1,值2,值3…);
# 插入多条记录
语法:
insert into 表名 values
(值1,值2,值3…值n),
(值1,值2,值3…值n),
(值1,值2,值3…值n);
# 插入查询结果
语法:
insert into 表名(字段1,字段2,字段3…字段n)
select (字段1,字段2,字段3…字段n) from 表2
where …;
语法:
update 表名 set
字段1=值1,
字段2=值2,
where 条件;
示例:
UPDATE mysql.user SET password=password(‘123’)
where user=’root’ and host=’localhost’;
语法:
delete from 表名
where 条件;
示例:
delete from mysql.user
where password=’’;
单表查询语法
SELECT DISTINCT 字段1,字段2... FROM 表名
WHERE 条件
GROUP BY field
HAVING 筛选
ORDER BY field
LIMIT 限制条数
关键字执行的优先级
关键字 | 作用 |
---|---|
from | 找到表 |
where | 拿着where指定的约束条件,去文件/表中取出一条条记录 |
group by | 将取出的一条条记录进行分组group by,如果没有group by,则整体作为一组 |
having | 将分组的结果进行having过滤 |
select distinct | 执行select(去重) |
order by | 将结果按条件排序:order by |
limit | 限制结果的显示条数 |
简单查询
# 示例表的信息
mysql> create table employee(
-> id int primary key auto_increment,
-> emp_name varchar(20) not null,
-> sex enum('男','女') not null default '男', # 大部分是男的
-> age int(3) unsigned not null default 18,
-> hire_date date not null,
-> post varchar(50),
-> post_comment varchar(100),
-> salary double(15,2),
-> office int, # 一个部门一个屋子
-> depart_id int
-> );
mysql> desc employee;
+--------------+-------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| emp_name | varchar(20) | NO | | NULL | |
| sex | enum('男','女') | NO | | 男 | |
| age | int(3) unsigned | NO | | 18 | |
| hire_date | date | NO | | NULL | |
| post | varchar(50) | YES | | NULL | |
| post_comment | varchar(100) | YES | | NULL | |
| salary | double(15,2) | YES | | NULL | |
| office | int(11) | YES | | NULL | |
| depart_id | int(11) | YES | | NULL | |
+--------------+-------------------+------+-----+---------+----------------+
mysql> insert into employee(emp_name,sex,age,hire_date,post,salary,office,depart_id) values
-> ('孙悟空','男',18,'20170301','develop',7300,401,1), # 以下是开发部门
-> ('猪八戒','男',78,'20150302','develop',1000000,401,1),
-> ('唐僧','男',81,'20130305','develop',8300,401,1),
-> ('小白龙','男',73,'20140701','develop',3500,401,1),
-> ('沙悟净','男',28,'20121101','develop',2100,401,1),
-> ('太上老君','女',18,'20110211','develop',9000,401,1),
-> ('元始天尊','男',18,'19000301','develop',30000,401,1),
-> ('通天教主','男',48,'20101111','develop',10000,401,1),
->
-> ('歪歪','女',48,'20150311','sale',3000,402,2),# 以下是销售部门
-> ('丫丫','女',38,'20101101','sale',2000,402,2),
-> ('丁丁','女',18,'20110312','sale',1000,402,2),
-> ('星星','女',18,'20160513','sale',3000,402,2),
-> ('格格','女',28,'20170127','sale',4000,402,2),
->
-> ('李世民','男',28,'20160311','operation',10000,403,3), # 以下是运营部门
-> ('程咬金','男',18,'19970312','operation',20000,403,3),
-> ('程咬银','女',18,'20130311','operation',19000,403,3),
-> ('程咬铜','男',18,'20150411','operation',18000,403,3),
-> ('程咬铁','女',18,'20140512','operation',17000,403,3)
-> ;
# 简单查询
mysql> select * from employee;
mysql> select emp_name,salary from employee;
# 避免重复DISTINCT
mysql> select distinct post from employee;
# 通过四则运算查询
mysql> select emp_name,salary*12 from employee;
# 定义显示格式 concat() 函数用于连接字符串
mysql> select concat('姓名:',emp_name,' 年薪:',salary*12) as Annual_salary
# as 新字段名
-> from employee;
mysql> select concat('姓名:',emp_name,' 年薪:',salary*12) Annual_salary
-> from employee; # 不用as也可以
+---------------------------------------+
| Annual_salary |
+---------------------------------------+
| 姓名:孙悟空 年薪:87600.00 |
| ... |
+---------------------------------------+
# CONCAT_WS() 第一个参数为连接符
mysql> select concat_ws(':',emp_name,salary*12) as Annual_salary
-> from employee;
+------------------------+
| Annual_salary |
+------------------------+
| 孙悟空:87600.00 |
| ... |
+------------------------+
# 结合case语句
mysql> select
-> ( case
-> when emp_name='通天教主' then
-> emp_name
-> when emp_name='孙悟空' then
-> concat(emp_name,'齐天大圣')
-> else
-> concat(emp_name,'打工仔')
-> end ) as person
-> from employee;
where约束
select 字段名 from 表名 where 条件
类型 | 用法 |
---|---|
比较运算符 | > < >= <= <> != |
between 80 and 100 | 值在80到100之间(包含80,100) |
in(80,90,100) | 值是80或90或100 |
like ‘e%‘ | 通配符可以是%或_,%表示任意多字符, _表示一个字符 |
regexp | 正则匹配 |
is / is not | is null / is not null |
逻辑运算符 | and or not |
# 1:单条件查询
mysql> select emp_name from employee
-> where post='sale';
# 2:多条件查询
mysql> select emp_name,salary from employee
-> where post='develop' and salary>10000;
# 3:关键字between on
mysql> select emp_name,salary from employee
-> where salary between 10000 and 20000;
mysql> select emp_name,salary from employee
-> where salary not between 10000 and 20000;
# 4:关键字IS NULL(判断某个字段是否为NULL不能用等号,需要用IS)
mysql> select emp_name,post_comment from employee
-> where post_comment is null;
mysql> select emp_name,post_comment from employee
-> where post_comment is not null;
mysql> select emp_name,post_comment from employee
-> where post_comment=''; # 注意''是空字符串,不是null
# 5:关键字IN集合查询
mysql> select emp_name,salary from employee
-> where salary=3000 or salary=3500 or salary=4000 or salary=9000;
mysql> select emp_name,salary from employee
-> where salary in(3000,3500,4000,9000);
mysql> select emp_name,salary from employee
-> where salary not in (3000,3500,4000,9000);
# 6:关键字like模糊查询
# 通配符’%’
mysql> select * from employee
-> where emp_name like('程%');
# 通配符’_’
mysql> select * from employee
-> where emp_name like('程咬_');
group by分组
根据某个重复率比较高的字段进行的,这个字段有多少种可能就分成多少组,能够做到去重,一旦分组了就不能对具体某一条数据进行操作了,永远都是考虑这个组的操作.对unique字段进行分组毫无意义.
单独使用group by关键字分组
select post from employee group by post;
注意: 我们按照post字段分组,那么select查询的字段只能是post,想要获取组内的其他相关信息,需要借助函数
group_concat(): 只用于做最终的显示,不能作为中间结果操作其他数据
group by与聚合函数一起使用:
select post,conut(id) as count from employee group by post; 按照岗位分组,并查看每个组有多少人
聚合函数
绝大多数情况是和分组一起使用的,如果没有和分组一起使用,那么一整张表就是一组
聚合函数 | 作用 |
---|---|
count() | 计数:每个组对应几条数据 |
max() | 求最大值:这个组中某字段的最大值 |
min() | 求最大值:这个组中某字段的最小值 |
avg() | 求平均值 |
sum() | 求和 |
# 示例
# 查询男员工个数与男员工的平均薪资,女员工个数与女员工的平均薪资
select sex,count(id),avg(salary) from employee group by sex;
# 查询岗位名以及各岗位的最高薪资
select post,max(salary) from employee group by post;
having过滤
主要用于对组进行筛选
和where不同在于:
# 执行优先级从高到低:where > group by > having
# 1. Where 发生在分组group by之前,因而Where中可以有任意字段,但是绝对不能使用聚合函数
# 2. Having发生在分组group by之后,因而Having中可以使用分组的字段,无法直接取到其他字段,可以使用聚合函数
order by查询排序
按单列排序:
select * from employee order by salary; 默认升序
select * from employee order by salary asc; 升序
select * from employee order by salary desc; 降序
按多列排序: 先按照age排序,如果年纪相同,则按照薪资排序
select * from employee order by age asc,salary desc;
limit限制查询的记录数
1.显示分页
2.取前n名,总是跟order by一起用
示例:
# 默认初始位置为0
select * from employee order by salary desc limit 3;
# 从第m开始,即先查询出第m+1条,然后包含这一条在内往后查n条
select * from employee order by salary desc limit m,n;
select * from employee order by salary desc limit n offset m; # 同上,从m+1开始取条
一, 连表查询
示例用表
# 建表
mysql> create table post(
-> id int,
-> name varchar(20)
-> );
mysql> create table employee(
-> id int primary key auto_increment,
-> name varchar(20),
-> sex enum('男','女') not null default '男',
-> age int,
-> post_id int
-> );
# 插入数据
mysql> insert into post values
-> (200,'技术'),
-> (201,'人力资源'),
-> (202,'销售'),
-> (203,'运营');
mysql> insert into employee(name,sex,age,post_id) values
-> ('孙悟空','男',18,200),
-> ('猪八戒','女',48,201),
-> ('沙悟净','男',38,201),
-> ('唐僧','女',28,202),
-> ('小白龙','男',18,200),
-> ('哪吒','女',18,204)
-> ;
# 查看数据
mysql> select * from post;
+------+--------------+
| id | name |
+------+--------------+
| 200 | 技术 |
| 201 | 人力资源 |
| 202 | 销售 |
| 203 | 运营 |
+------+--------------+
mysql> select * from employee;
+----+-----------+-----+------+---------+
| id | name | sex | age | post_id |
+----+-----------+-----+------+---------+
| 1 | 孙悟空 | 男 | 18 | 200 |
| 2 | 猪八戒 | 女 | 48 | 201 |
| 3 | 沙悟净 | 男 | 38 | 201 |
| 4 | 唐僧 | 女 | 28 | 202 |
| 5 | 小白龙 | 男 | 18 | 200 |
| 6 | 哪吒 | 女 | 18 | 204 |
+----+-----------+-----+------+---------+
语法
select 字段 from 表1 inner/left/right join 表2
on 表1.字段 = 表2.字段;
交叉连接: 不适用任何匹配条件,生成笛卡尔积,再根据条件进行筛选,但是不能对查询到表再进行操作
mysql> select * from employee,post where post_id=post.id;
+----+-----------+-----+------+---------+------+--------------+
| id | name | sex | age | post_id | id | name |
+----+-----------+-----+------+---------+------+--------------+
| 1 | 孙悟空 | 男 | 18 | 200 | 200 | 技术 |
| 2 | 猪八戒 | 女 | 48 | 201 | 201 | 人力资源 |
| 3 | 沙悟净 | 男 | 38 | 201 | 201 | 人力资源 |
| 4 | 唐僧 | 女 | 28 | 202 | 202 | 销售 |
| 5 | 小白龙 | 男 | 18 | 200 | 200 | 技术 |
+----+-----------+-----+------+---------+------+--------------+
内连接: 只会显示两张表中互相匹配的项,其他不匹配的不显示
# select * from 表1 inner join 表2 on 条件;
# 找两张表共有的部分,相当于利用条件从笛卡尔积结果中筛选出了正确的结果
# post没有204这个部门,因而employee表中关于204这条员工信息没有匹配出来
mysql> select e.id,e.name,age,sex,p.name from employee as e inner join post as p on post_id=p.id;
+----+-----------+------+-----+--------------+
| id | name | age | sex | name |
+----+-----------+------+-----+--------------+
| 1 | 孙悟空 | 18 | 男 | 技术 |
| 2 | 猪八戒 | 48 | 女 | 人力资源 |
| 3 | 沙悟净 | 38 | 男 | 人力资源 |
| 4 | 唐僧 | 28 | 女 | 销售 |
| 5 | 小白龙 | 18 | 男 | 技术 |
+----+-----------+------+-----+--------------+
外连接之左连接: 不管左表中是不是匹配上都会显示所有内容
# select * from 表1 left join 表2 on 条件;
# 以左表为准,即找出所有员工信息,当然包括没有部门的员工
# 本质就是: 在内连接的基础上增加左边有右边没有的结果
mysql> select e.id,e.name,post.name as post_name from employee as e left join post on post_id=post.id;
+----+-----------+--------------+
| id | name | post_name |
+----+-----------+--------------+
| 1 | 孙悟空 | 技术 |
| 5 | 小白龙 | 技术 |
| 2 | 猪八戒 | 人力资源 |
| 3 | 沙悟净 | 人力资源 |
| 4 | 唐僧 | 销售 |
| 6 | 哪吒 | NULL |
+----+-----------+--------------+
外链接之右连接: 不管右表中是不是匹配上都会显示所有内容
# select * from 表1 right join 表2 on 条件
# 以右表为准,即找出所有部门信息,包括没有员工的部门
# 本质就是: 在内连接的基础上增加右边有左边没有的结果
mysql> select e.id,e.name,post.name as post_name from employee as e right join post on post_id=post.id;
+------+-----------+--------------+
| id | name | post_name |
+------+-----------+--------------+
| 1 | 孙悟空 | 技术 |
| 2 | 猪八戒 | 人力资源 |
| 3 | 沙悟净 | 人力资源 |
| 4 | 唐僧 | 销售 |
| 5 | 小白龙 | 技术 |
| NULL | NULL | 运营 |
+------+-----------+--------------+
全外连接: 显示左右两个表全部记录
# 全外连接:在内连接的基础上增加左边有右边没有的和右边有左边没有的结果
# 注意:mysql不支持全外连接 full join
# 强调:mysql可以使用此种方式间接实现全外连接
# select * from 表1 left join 表2 on 条件
# union
# select * from 表1 right join 表2 on 条件;
mysql> select e.id,e.name,post.name as post_name from employee as e left join post on post_id=post.id
-> union
-> select e.id,e.name,post.name as post_name from employee as e right join post on post_id=post.id;
+------+-----------+--------------+
| id | name | post_name |
+------+-----------+--------------+
| 1 | 孙悟空 | 技术 |
| 5 | 小白龙 | 技术 |
| 2 | 猪八戒 | 人力资源 |
| 3 | 沙悟净 | 人力资源 |
| 4 | 唐僧 | 销售 |
| 6 | 哪吒 | NULL |
| NULL | NULL | 运营 |
+------+-----------+--------------+
# 注意 union与union all的区别: union会去掉相同的纪录
符合条件连接查询
# 示例1:以内连接的方式查询employee和psot表,并且employee表中的age字段值必须大于25,即找出年龄大于25岁的员工以及员工所在的部门
mysql> select e.name,post.name as post_name from employee as e inner join post on post_id=post.id where age>25;
+-----------+--------------+
| name | post_name |
+-----------+--------------+
| 猪八戒 | 人力资源 |
| 沙悟净 | 人力资源 |
| 唐僧 | 销售 |
+-----------+--------------+
# 示例2:以内连接的方式查询employee和post表,并且以age字段的升序方式显示
mysql> select e.name,age,post.name as post_name,post_id from employee as e inner join post on post_id=post.id order by age;
+-----------+------+--------------+---------+
| name | age | post_name | post_id |
+-----------+------+--------------+---------+
| 孙悟空 | 18 | 技术 | 200 |
| 小白龙 | 18 | 技术 | 200 |
| 唐僧 | 28 | 销售 | 202 |
| 沙悟净 | 38 | 人力资源 | 201 |
| 猪八戒 | 48 | 人力资源 | 201 |
+-----------+------+--------------+---------+
二, 子查询
# 1:子查询是将一个查询语句嵌套在另一个查询语句中.
# 2:内层查询语句的查询结果,可以为外层查询语句提供查询条件。
# 3:子查询中可以包含:IN、NOT IN、ANY、ALL、EXISTS 和 NOT EXISTS等关键字
# 4:还可以包含比较运算符:= 、 !=、> 、<等
带in关键字的子查询
# 查询平均年龄在25岁以上的部门名
mysql> select name from post where id in (select post_id from employee group by post_id having avg(age)>25);
+--------------+
| name |
+--------------+
| 人力资源 |
| 销售 |
+--------------+
# 查看技术部员工姓名
mysql> select name from employee where post_id=(select id from post where name='技术');
+-----------+
| name |
+-----------+
| 孙悟空 |
| 小白龙 |
+-----------+
# 查看不足1人的部门名(子查询得到的是有人的部门id)
mysql> select name from post where id not in (select post_id from employee);
+--------+
| name |
+--------+
| 运营 |
+--------+
带比较运算符的子查询
# 查询大于所有人平均年龄的员工名与年龄
mysql> select name,age from employee where age>(select avg(age) from employee);
+-----------+------+
| name | age |
+-----------+------+
| 猪八戒 | 48 |
| 沙悟净 | 38 |
+-----------+------+
# 查询大于部门内平均年龄的员工名、年龄
mysql> select name,post_id from employee inner join (select post_id as post_id2,avg(age) as avg_age from employee group by post_id) as emp on post_id=post_id2 where age>avg_age;
+-----------+---------+
| name | post_id |
+-----------+---------+
| 猪八戒 | 201 |
+-----------+---------+
带exists关键字的子查询
exists关键字表示存在,在使用exists关键字时,内层查询语句不返回查询的记录.而是返回一个真假值,True或False.当返回True时,外层查询语句将进行查询;当返回值为False时,外层查询语句不进行查询
# post表中存在id=200,Ture
mysql> select * from employee
-> where exists
-> (select id from psot where id=200);
# post表中不存在id=205,False
mysql> select * from employee
-> where exists
-> (select id from post where id=205);
练习: 查询每个部门最新入职的那位员工
# 准备表和数据
mysql> create table emp(
-> id int primary key auto_increment,
-> emp_name varchar(20) not null,
-> sex enum('男','女') not null default '男', # 大部分是男的
-> age int(3) unsigned not null default 18,
-> hire_date date not null,
-> post varchar(50),
-> post_comment varchar(100),
-> salary double(15,2),
-> office int, # 一个部门一个屋子
-> depart_id int
-> );
mysql> insert into emp(emp_name,sex,age,hire_date,post,salary,office,depart_id) values
-> ('孙悟空','男',18,'20170301','develop',7300,401,1), # 以下是开发部门
-> ('猪八戒','男',78,'20150302','develop',1000000,401,1),
-> ('唐僧','男',81,'20130305','develop',8300,401,1),
-> ('小白龙','男',73,'20140701','develop',3500,401,1),
-> ('沙悟净','男',28,'20121101','develop',2100,401,1),
-> ('太上老君','女',18,'20110211','develop',9000,401,1),
-> ('元始天尊','男',18,'19000301','develop',30000,401,1),
-> ('通天教主','男',48,'20101111','develop',10000,401,1),
-> ('歪歪','女',48,'20150311','sale',3000,402,2),# 以下是销售部门
-> ('丫丫','女',38,'20101101','sale',2000,402,2),
-> ('丁丁','女',18,'20110312','sale',1000,402,2),
-> ('星星','女',18,'20160513','sale',3000,402,2),
-> ('格格','女',28,'20170127','sale',4000,402,2),
-> ('李世民','男',28,'20160311','operation',10000,403,3), # 以下是运营部门
-> ('程咬金','男',18,'19970312','operation',20000,403,3),
-> ('程咬银','女',18,'20130311','operation',19000,403,3),
-> ('程咬铜','男',18,'20150411','operation',18000,403,3),
-> ('程咬铁','女',18,'20140512','operation',17000,403,3);
# 连表查询
mysql> select emp.post,emp_name,max_date from emp inner join (select post,max(hire_date) as max_date from emp group by post) as emp2
-> on emp.post=emp2.post where hire_date=max_date;
+-----------+-----------+------------+
| post | emp_name | max_date |
+-----------+-----------+------------+
| develop | 孙悟空 | 2017-03-01 |
| sale | 格格 | 2017-01-27 |
| operation | 李世民 | 2016-03-11 |
+-----------+-----------+------------+
# 子查询 有缺陷
mysql> select emp_name,hire_date,post from (select * from emp order by hire_date desc) as emp2 group by post;
+-----------+------------+-----------+
| emp_name | hire_date | post |
+-----------+------------+-----------+
| 孙悟空 | 2017-03-01 | develop |
| 李世民 | 2016-03-11 | operation |
| 格格 | 2017-01-27 | sale |
+-----------+------------+-----------+
mysql> select emp_name,hire_date,post from emp where id in(
-> select (select id from emp as t2 where t2.post=t1.post order by hire_date desc limit 1) from emp as t1 group by post
-> );
+-----------+------------+-----------+
| emp_name | hire_date | post |
+-----------+------------+-----------+
| 孙悟空 | 2017-03-01 | develop |
| 格格 | 2017-01-27 | sale |
| 李世民 | 2016-03-11 | operation |
+-----------+------------+-----------+
# 每个部门可能有>1个为同一时间入职的新员工
# 说明,子查询可以在select后(要求查询的结果必须是一个单行单列的值)和from后使用
mysql记录操作
标签:like 匹配 name 数据 返回值 包括 插入 指定 多表查询