[TOC]
# **SQL语言**
* 数据表操作:创建、删除
* 数据操作:增加、删除、修改、简单查询
* 数据操作:查询
> 此部分中查询为重点,需要熟练掌握
* SQL语言编写和运行
* 鼠标左键点击某个数据库下面的查询按钮,然后点击新建查询
![](https://i.niupic.com/images/2020/08/03/8udi.png)
* 在打开的查询编辑器中,编写SQL语言,再点击运行
![](https://i.niupic.com/images/2020/08/03/8udk.png)
<br />
## **数据表操作**
**创建表**
```
create table 表名(
字段名 类型 约束,
字段名 类型 约束
...
);
```
例:创建学生表,字段要求如下:
姓名(长度为10)
```
create table students(
name varchar(10)
);
```
例:创建学生表,字段要求如下:
姓名(长度为10), 年龄
```
create table students(
name varchar(10),
age int unsigned
);
```
例:创建学生表,字段要求如下:
姓名(长度为10), 年龄,身高(保留小数点2位)
```
create table students(
id int unsigned primary key auto_increment,
name varchar(20),
age int unsigned,
height decimal(5,2)
);
```
删除表
```
格式一:drop table 表名;
格式二:drop table if exists 表名;
```
例:删除学生表
```
drop table students;
或
drop table if exists students;
```
<br />
## **数据操作\-增删改查**
**简单查询**
```
select * from 表名;
例:查询所有学生数据
select * from students;
```
**添加数据**
添加一行数据
格式一:所有字段设置值,值的顺序与表中字段的顺序对应
* 说明:主键列是自动增长,插入时需要占位,通常使用0或者 default 或者 null 来占位,插入成功后以实际数据为准
```
insert into 表名 values(...);
```
例:插入一个学生,设置所有字段的信息
```
insert into students values(0,'亚瑟',22,177.56);
```
格式二:部分字段设置值,值的顺序与给出的字段顺序对应
```
insert into 表名(字段1,...) values(值1,...);
```
例:插入一个学生,只设置姓名
```
insert into students(name) values('老夫子');
```
添加多行数据
方式一:写多条insert语句,语句之间用英文分号隔开
```
insert into students(name) values('老夫子2');
insert into students(name) values('老夫子3');
insert into students values(0,'亚瑟2',23,167.56);
```
方式二:写一条insert语句,设置多条数据,数据之间用英文逗号隔开
```
格式一:insert into 表名 values(...),(...)...
例:插入多个学生,设置所有字段的信息
insert into students values(0,'亚瑟3',23,167.56),(0,'亚瑟4',23,167.56);
```
```
格式二:insert into 表名(列1,...) values(值1,...),(值1,...)...
例:插入多个学生,只设置姓名
insert into students(name) values('老夫子5'),('老夫子6');
```
修改
```
格式:update 表名 set 列1=值1,列2=值2... where 条件;
```
例:修改id为5的学生数据,姓名改为 狄仁杰,年龄改为 20
```
update students set name='狄仁杰',age=20 where id=5;
```
删除
```
格式:delete from 表名 where 条件;
```
例:删除id为6的学生数据
```
delete from students where id=6;
```
逻辑删除:对于重要的数据,不能轻易执行delete语句进行删除,一旦删除,数据无法恢复,这时可以进行逻辑删除。
1、给表添加字段,代表数据是否删除,一般起名isdelete,0代表未删除,1代表删除,默认值为0
2、当要删除某条数据时,只需要设置这条数据的isdelete字段为1
3、以后在查询数据时,只查询出isdelete为0的数据
```
例:
1、给学生表添加字段(isdelete),默认值为0,如果表中已经有数据,需要把所有数据的isdelete字段更新为0
update students set isdelete=0
2、删除id为1的学生
update students set isdelete=1 where id=1;
3、查询未删除的数据
select * from students where iddelete=0;
```
<br />
## **数据操作\-查询**
**创建数据表**
```
drop table if exists students;
create table students (
studentNo varchar(10) primary key,
name varchar(10),
sex varchar(1),
hometown varchar(20),
age tinyint(4),
class varchar(10),
card varchar(20)
);
```
**准备数据**
```
insert into students values
('001', '王昭君', '女', '北京', '20', '1班', '340322199001247654'),
('002', '诸葛亮', '男', '上海', '18', '2班', '340322199002242354'),
('003', '张飞', '男', '南京', '24', '3班', '340322199003247654'),
('004', '白起', '男', '安徽', '22', '4班', '340322199005247654'),
('005', '大乔', '女', '天津', '19', '3班', '340322199004247654'),
('006', '孙尚香', '女', '河北', '18', '1班', '340322199006247654'),
('007', '百里玄策', '男', '山西', '20', '2班', '340322199007247654'),
('008', '小乔', '女', '河南', '15', '3班', null),
('009', '百里守约', '男', '湖南', '21', '1班', ''),
('010', '妲己', '女', '广东', '26', '2班', '340322199607247654'),
('011', '李白', '男', '北京', '30', '4班', '340322199005267754'),
('012', '孙膑', '男', '新疆', '26', '3班', '340322199000297655');
```
查询所有字段
```
select * from 表名;
例:
select * from students;
```
查询指定字段
在select后面的列名部分,可以使用as为列起别名,这个别名出现在结果集中
```
select 列1,列2,... from 表名;
-- 表名.字段名
select students.name,students.age from students;
-- 可以通过 as 给表起别名
select s.name,s.age from students as s;
-- 如果是单表查询 可以省略表明
select name,age from students;
- 使用as给字段起别名
select studentNo as 学号,name as 名字,sex as 性别 from students;
```
消除重复行
在select后面列前使用distinct可以消除重复的行
```
select distinct 列1,... from 表名;
例:
select distinct sex from students;
```
<br />
### **条件**
* 使用where子句对表中的数据筛选,符号条件的数据会出现在结果集中
* 语法如下:
```
select 字段1,字段2... from 表名 where 条件;
例:
select * from students where id=1;
```
* where后面支持多种运算符,进行条件的处理
* * 比较运算
* * 逻辑运算
* * 模糊查询
* * 范围查询
* * 空判断
**比较运算符**
* * 等于: =
* * 大于: >
* * 大于等于: >=
* * 小于: <
* * 小于等于: <=
* * 不等于: != 或 <>
例1:查询小乔的年龄
```
select age from students where name='小乔'
```
例2:查询20岁以下的学生
```
select * from students where age<20
```
例3:查询家乡不在北京的学生
```
select * from students where hometown!='北京'
```
练习:
```
1、查询学号是'007'的学生的身份证号
2、查询'1班'以外的学生信息
3、查询年龄大于20的学生的姓名和性别
```
**逻辑运算符**
* and
* or
* not
例1:查询年龄小于20的女同学
```
select * from students where age<20 and sex='女'
```
例2:查询女学生或'1班'的学生
```
select * from students where sex='女' or class='1班'
```
例3:查询非天津的学生
```
select * from students where not hometown='天津'
```
练习:
```
1、查询河南或河北的学生
2、查询'1班'的'上海'的学生
3、查询非20岁的学生
```
**模糊查询**
* like
* %表示任意多个任意字符
* _表示一个任意字符
例1:查询姓孙的学生
```
select * from students where name like '孙%'
```
例2:查询姓孙且名字是一个字的学生
```
select * from students where name like '孙_'
```
例3:查询叫乔的学生
```
select * from students where name like '%乔'
```
例4:查询姓名含白的学生
```
select * from students where name like '%白%'
```
练习:
```
1、查询姓名为两个字的学生
2、查询姓百且年龄大于20的学生
3、查询学号以1结尾的学生
```
范围查询
* in表示在一个非连续的范围内
例1:查询家乡是北京或上海或广东的学生
```
select * from students where hometown in('北京','上海','广东')
```
* between ... and ...表示在一个连续的范围内
例2:查询年龄为18至20的学生
```
select * from students where age between 18 and 20
```
练习:
```
1、查询年龄在18或19或22的女生
2、查询年龄在20到25以外的学生
```
**空判断**
* 注意:null与''是不同的
* 判空is null
例1:查询没有填写身份证的学生
```
select * from students where card is null
```
判非空is not null
例2:查询填写了身份证的学生
```
select * from students where card is not null
```
<br />
### **排序**
* 为了方便查看数据,可以对数据进行排序
* 语法:
```
select * from 表名
order by 列1 asc|desc,列2 asc|desc,...
```
* 将行数据按照列1进行排序,如果某些行列1的值相同时,则按照列2排序,以此类推
* 默认按照列值从小到大排列
* asc从小到大排列,即升序
* desc从大到小排序,即降序
例1:查询所有学生信息,按年龄从小到大排序
```
select * from students order by age
```
例2:查询所有学生信息,按年龄从大到小排序,年龄相同时,再按学号从小到大排序
```
select * from students order by age desc,studentNo
```
练习:
```
1、查询所有学生信息,按班级从小到大排序,班级相同时,再按学号再按学号从小到大排序
```
<br />
### **聚合函数**
* 为了快速得到统计数据,经常会用到如下5个聚合函数
* count(*)表示计算总行数,括号中写星与列名,结果是相同的
* 聚合函数不能在 where 中使用
例1:查询学生总数
```
select count(*) from students;
```
* max(列)表示求此列的最大值
例2:查询女生的最大年龄
```
select max(age) from students where sex='女';
```
* min(列)表示求此列的最小值
例3:查询1班的最小年龄
```
select min(age) from students;
```
* sum(列)表示求此列的和
例4:查询北京学生的年龄总和
```
select sum(age) from students where hometown='北京';
```
* avg(列)表示求此列的平均值
例5:查询女生的平均年龄
```
select avg(age) from students where sex='女'
```
练习:
```
1、查询所有学生的最大年龄、最小年龄、平均年龄
2、一班共有多少个学生
3、查询3班年龄小于18岁的同学有几个
```
<br />
### **分组**
* 按照字段分组,表示此字段相同的数据会被放到一个组中
* 分组后,分组的依据列会显示在结果集中,其他列不会显示在结果集中
* 可以对分组后的数据进行统计,做聚合运算
语法:
```
select 列1,列2,聚合... from 表名 group by 列1,列2...
```
例1:查询各种性别的人数
```
select sex,count(*) from students group by sex
```
例2:查询各种年龄的人数
```
select age,count(*) from students group by age
```
练习
```
查询各个班级学生的平均年龄、最大年龄、最小年龄
```
分组后的数据筛选
* 语法:
```
select 列1,列2,聚合... from 表名
group by 列1,列2,列3...
having 列1,...聚合...
```
* having后面的条件运算符与where的相同
例1:查询男生总人数
```
方案一
select count(*) from students where sex='男'
-----------------------------------
方案二:
select sex,count(*) from students group by sex having sex='男'
```
练习
```
查询1班除外其他班级学生的平均年龄、最大年龄、最小年龄
```
**对比where与having**
* where是对from后面指定的表进行数据筛选,属于对原始数据的筛选
* having是对group by的结果进行筛选
<br />
### **分页**
**获取部分行**
* 当数据量过大时,在一页中查看数据是一件非常麻烦的事情
* 语法
```
select * from 表名
limit start,count
```
* 从start开始,获取count条数据
* start索引从0开始
例1:查询前3行学生信息
```
select * from students limit 0,3
```
练习
```
查询第4到第6行学生信息
```
分页
* 已知:每页显示m条数据,求:显示第n页的数据
```
select * from students limit (n-1)*m,m
```
* 求总页数
* 查询总条数p1
* 使用p1除以m得到p2
* 如果整除则p2为总数页
* 如果不整除则p2+1为总页数
练习:
```
每页显示5条数据,显示每一页的数据
```
<br />
### **连接查询**
* 当查询结果的列来源于多张表时,需要将多张表连接成一个大的数据集,再选择合适的列返回
* 等值连接查询:查询的结果为两个表匹配到的数据
![](https://i.niupic.com/images/2020/08/04/8uoN.png)
* 左连接查询:查询的结果为两个表匹配到的数据加左表特有的数据,对于右表中不存在的数据
使用null填充
![](https://i.niupic.com/images/2020/08/04/8uoP.png)
* 右连接查询:查询的结果为两个表匹配到的数据加右表特有的数据,对于左表中不存在的数据
使用null填充
![](https://i.niupic.com/images/2020/08/04/8uoR.png)
准备数据
```
drop table if exists courses;
create table courses (
courseNo int(10) unsigned primary key auto_increment,
name varchar(10)
);
insert into courses values
('1', '数据库'),
('2', 'qtp'),
('3', 'linux'),
('4', '系统测试'),
('5', '单元测试'),
('6', '测试过程');
```
```
drop table if exists scores;
create table scores (
id int(10) unsigned primary key auto_increment,
courseNo int(10),
studentno varchar(10),
score tinyint(4)
);
insert into scores values
('1', '1', '001', '90'),
('2', '1', '002', '75'),
('3', '2', '002', '98'),
('4', '3', '001', '86'),
('5', '3', '003', '80'),
('6', '4', '004', '79'),
('7', '5', '005', '96'),
('8', '6', '006', '80');
```
<br />
**等值连接**
方式一
```
select * from 表1,表2 where 表1.列\=表2.列
```
方式二(又称内连接)
```
select * from 表1
inner join 表2 on 表1.列=表2.列
```
例1:查询学生信息及学生的成绩
```
select
*
from
students stu,
scores sc
where
stu.studentNo = sc.studentNo
---------------------------------------
select
*
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
```
例2:查询课程信息及课程的成绩
```
select
*
from
courses cs,
scores sc
where
cs.courseNo = sc.courseNo
---------------------------------------
select
*
from
courses cs
inner join scores sc on cs.courseNo = sc.courseNo
```
例3:查询学生信息及学生的课程对应的成绩
```
select
*
from
students stu,
courses cs,
scores sc
where
stu.studentNo = sc.studentno
and cs.courseNo = sc.courseNo
---------------------------------------
select
*
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on cs.courseNo = sc.courseNo
```
例4:查询王昭君的成绩,要求显示姓名、课程号、成绩
```
select
stu.name,
sc.courseNo,
sc.score
from
students stu,
scores sc
where
stu.studentNo = sc.studentNo
and stu.name = '王昭君'
---------------------------------------
select
stu.name,
sc.courseNo,
sc.score
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
where
stu.name = '王昭君'
```
例5:查询王昭君的数据库成绩,要求显示姓名、课程名、成绩
```
select
stu.name,
cs.name,
sc.score
from
students stu,
scores sc,
courses cs
where
stu.studentNo = sc.studentNo
and sc.courseNo = cs.courseNo
and stu.name = '王昭君'
and cs.name = '数据库'
---------------------------------------
select
stu.name,
cs.name,
sc.score
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on sc.courseNo = cs.courseNo
where
stu.name = '王昭君' and cs.name = '数据库'
```
例6:查询所有学生的数据库成绩,要求显示姓名、课程名、成绩
```
select
stu.name,
cs.name,
sc.score
from
students stu,
scores sc,
courses cs
where
stu.studentNo = sc.studentNo
and sc.courseNo = cs.courseNo
and cs.name = '数据库'
---------------------------------------
select
stu.name,
cs.name,
sc.score
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on sc.courseNo = cs.courseNo
where
cs.name = '数据库'
```
例7:查询男生中最高成绩,要求显示姓名、课程名、成绩
```
select
stu.name,
cs.name,
sc.score
from
students stu,
scores sc,
courses cs
where
stu.studentNo = sc.studentNo
and sc.courseNo = cs.courseNo
and stu.sex = '男'
order by
sc.score desc
limit 1
--------------------------------------
select
stu.name,
cs.name,
sc.score
from
students stu
inner join scores sc on stu.studentNo = sc.studentNo
inner join courses cs on sc.courseNo = cs.courseNo
where
stu.sex = '男'
order by
sc.score desc
limit 1
```
<br />
**左连接**
```
select * from 表1
left join 表2 on 表1.列\=表2.列
```
例1:查询所有学生的成绩,包括没有成绩的学生
```
select
*
from
students stu
left join scores sc on stu.studentNo = sc.studentNo
```
例2:查询所有学生的成绩,包括没有成绩的学生,需要显示课程名
```
select
*
from
students stu
left join scores sc on stu.studentNo = sc.studentNo
left join courses cs on cs.courseNo = sc.courseNo
```
右连接
```
select * from 表1
right join 表2 on 表1.列=表2.列
```
```
添加两门课程
insert into courses values
(0, '语文'),
(0, '数学');
```
例1:查询所有课程的成绩,包括没有成绩的课程
```
select
*
from
scores sc
right join courses cs on cs.courseNo = sc.courseNo
```
例2:查询所有课程的成绩,包括没有成绩的课程,包括学生信息
```
select
*
from
scores sc
right join courses cs on cs.courseNo = sc.courseNo
left join students stu on stu.stud
```
<br />
### **自关联**
* 设计省信息的表结构provinces
* id
* ptitle
* 设计市信息的表结构citys
* id
* ctitle
* proid
* citys表的proid表示城市所属的省,对应着provinces表的id值
* 问题:能不能将两个表合成一张表呢?
* 思考:观察两张表发现,citys表比provinces表多一个列proid,其它列的类型都是一样的
* 意义:存储的都是地区信息,而且每种信息的数据量有限,没必要增加一个新表,或者将来还
要存储区、乡镇信息,都增加新表的开销太大
* 答案:定义表areas,结构如下
* * id
* * atitle
* * pid
* 因为省没有所属的省份,所以可以填写为null
* 城市所属的省份pid,填写省所对应的编号id
* 这就是自关联,表中的某一列,关联了这个表中的另外一列,但是它们的业务逻辑含义是不一
样的,城市信息的pid引用的是省信息的id
* 在这个表中,结构不变,可以添加区县、乡镇街道、村社区等信息
准备数据:
```
create table areas(
aid int primary key,
atitle varchar(20),
pid int
);
insert into areas
values ('130000', '河北省', NULL),
('130100', '石家庄市', '130000'),
('130400', '邯郸市', '130000'),
('130600', '保定市', '130000'),
('130700', '张家口市', '130000'),
('130800', '承德市', '130000'),
('410000', '河南省', NULL),
('410100', '郑州市', '410000'),
('410300', '洛阳市', '410000'),
('410500', '安阳市', '410000'),
('410700', '新乡市', '410000'),
('410800', '焦作市', '410000');
```
* 例1:查询一共有多少个省
```
select count(*) from areas where pid is null;
```
例1:查询河南省的所有城市
```
select
*
from
areas as p
inner join areas as c on c.pid=p.aid
where
p.atitle='河北省';
```
```
添加区县数据
insert into areas values
('410101', '中原区', '410100'),
('410102', '二七区', '410100'),
('410103', '金水区', '410100');
```
例2:查询郑州市的所有区县
```
select
*
from
areas as c
inner join areas as a on a.pid=c.aid
where
c.atitle='郑州市';
```
例3:查询河南省的所有区县
```
select
*
from
areas as p
left join areas as c on c.pid=p.aid
left join areas as a on a.pid=c.aid
where
p.atitle='河南省'
```
<br />
### **子查询**
* 在一个 select 语句中,嵌入了另外一个 select 语句, 那么被嵌入的 select 语句称之为子查询语
句
**主查询**
* 主要查询的对象,第一条 select 语句
*
**主查询和子查询的关系**
* 子查询是嵌入到主查询中
* 子查询是辅助主查询的,要么充当条件,要么充当数据源
* 子查询是可以独立存在的语句,是一条完整的 select 语句
**子查询分类**
* 标量子查询: 子查询返回的结果是一个数据(一行一列)
* 列子查询: 返回的结果是一列(一列多行)
* 行子查询: 返回的结果是一行(一行多列)
* 表级子查询: 返回的结果是多行多列
**标量子查询**
例1:查询班级学生的平均年龄
```
查询班级学生平均年龄
select avg(age) from students
查询大于平均年龄的学生
select * from students where age > 21.4167
select * from students where age > (select avg(age) from students);
```
例2:查询王昭君的成绩,要求显示成绩
```
学生表中查询王昭君的学号
select studentNo from students where name = '王昭君'
成绩表中根据学号查询成绩
select * from scores where studentNo = '001'
select * from scores where studentNo = (select studentNo from students where name = '王昭君')
```
**列级子查询**
例3:查询18岁的学生的成绩,要求显示成绩
```
学生表中查询18岁的学生的学号
select studentNo from students where age=18
成绩表中根据学号查询成绩
select * from scores where studentNo in ('002','006')
select * from scores where studentNo in (select studentNo from students where age=18)
```
**行级子查询**
例4:查询男生中年龄最大的学生信息
```
select * from students where sex='男' and age=(select max(age) from students)
```
<br />
### **表级子查询**
例5:查询数据库和系统测试的课程成绩
```
select
*
from
scores s
inner join
(select * from courses where name in ('数据库','系统测试')) c
on s.courseNo = c.courseNo
```
**子查询中特定关键字使用**
* in 范围
* 格式: 主查询 where 条件 in (列子查询)
* any | some 任意一个
* 格式: 主查询 where 列 = any (列子查询)
* 在条件查询的结果中匹配任意一个即可,等价于 in
* all
* 格式: 主查询 where 列 = all(列子查询) : 等于里面所有
* 格式: 主查询 where 列 <>all(列子查询) : 不等一其中所有
```
select * from students where age in (select age from students where age between 18 and 20)
```
<br />
### **查询演练**
**准备数据**
```
create table goods(
id int unsigned primary key auto_increment,
name varchar(150),
cate varchar(40),
brand_name varchar(40),
price decimal(10,3) default 0,
is_show bit default 1,
is_saleoff bit default 0
);
insert into goods values(0,'r510vc 15.6英寸笔记本','笔记本','华硕','3399',default,default);
insert into goods values(0,'y400n 14.0英寸笔记本电脑','笔记本','联想','4999',default,default);
insert into goods values(0,'g150th 15.6英寸游戏本','游戏本','雷神','8499',default,default);
insert into goods values(0,'x550cc 15.6英寸笔记本','笔记本','华硕','2799',default,default);
insert into goods values(0,'x240 超极本','超级本','联想','4999',default,default);
insert into goods values(0,'u330p 13.3英寸超极本','超级本','联想','4299',default,default)
;
insert into goods values(0,'svp13226scb 触控超极本','超级本','索尼','7999',default,defaul
t);
insert into goods values(0,'ipad mini 7.9英寸平板电脑','平板电脑','苹果','1998',default,default);
insert into goods values(0,'ipad air 9.7英寸平板电脑','平板电脑','苹果','3388',default,default);
insert into goods values(0,'ipad mini 配备 retina 显示屏','平板电脑','苹果','2788',default,default);
insert into goods values(0,'ideacentre c340 20英寸一体电脑 ','台式机','联想','3499',default,default);
insert into goods values(0,'vostro 3800-r1206 台式电脑','台式机','戴尔','2899',default,default);
insert into goods values(0,'imac me086ch/a 21.5英寸一体电脑','台式机','苹果','9188',default,default);
insert into goods values(0,'at7-7414lp 台式电脑 linux )','台式机','宏碁','3699',default,default);
insert into goods values(0,'z220sff f4f06pa工作站','服务器/工作站','惠普','4288',default,default);
insert into goods values(0,'poweredge ii服务器','服务器/工作站','戴尔','5388',default,default);
insert into goods values(0,'mac pro专业级台式电脑','服务器/工作站','苹果','28888',default,default);
insert into goods values(0,'hmz-t3w 头戴显示设备','笔记本配件','索尼','6999',default,default);
insert into goods values(0,'商务双肩背包','笔记本配件','索尼','99',default,default);
insert into goods values(0,'x3250 m4机架式服务器','服务器/工作站','ibm','6888',default,de
fault);
insert into goods values(0,'hmz-t3w 头戴显示设备','笔记本配件','索尼','6999',default,default);
insert into goods values(0,'商务双肩背包','笔记本配件','索尼','99',default,default);
```
**查询演练**
> 求所有电脑产品的平均价格,并且保留两位小数
```
select round(avg(price),2) as avg_price from goods;
```
> 查询所有价格大于平均价格的商品,并且按价格降序排序
```
select id,name,price from goods
where price > (select round(avg(price),2) as avg_price from goods)
order by price desc;
```
> 查询类型为'超极本'的商品价格
```
select price from goods where cate = '超级本';
```
> 查询价格大于或等于"超级本"价格的商品,并且按价格降序排列
```
select id,name,price from goods
where price >= any(select price from goods where cate = '超级本')
order by price desc;
```
> = any 或者 =some 等价 in
```
select id,name,price from goods
where price in (select price from goods where cate = '超级本')
order by price desc;
```
> !=all 等价于 not in
```
select id,name,price from goods
where price not in (select price from goods where cate = '超级本')
order by price desc;
```
<br />
**数据分表**
> 创建“商品分类”表
```
create table if not exists goods_cates(
cate_id int unsigned primary key auto_increment,
cate_name varchar(40)
);
```
> 查询goods表的所有记录,并且按"类别"分组
```
select cate from goods group by cate;
```
> 将分组结果写入到goods_cates数据表
```
insert into goods_cates (cate_name) select cate from goods group by cate;
```
> 通过goods_cates数据表来更新goods表
```
update goods as g inner join goods_cates as c on g.cate = c.cate_name
set cate = cate_id;
```
> 通过create...select来创建数据表并且同时写入记录,一步到位
```
create table goods_brands (
brand_id int unsigned primary key auto_increment,
brand_name varchar(40)) select brand_name from goods group by brand_name;
```
> 通过goods_brands数据表来更新goods数据表
```
update goods as g inner join goods_brands as b on g.brand_name = b.brand_name
set g.brand_name = b.brand_id;
```
> 查看 goods 的数据表结构,会发现 cate 和 brand_name对应的类型为 varchar 但是存储的都
> 是字符串
> 修改数据表结构,把cate字段改为cate_id且类型为int unsigned,把brand_name字段改为
> brand_id且类型为int unsigned
> 分别在 good_scates 和 goods_brands表中插入记录
```
insert into goods_cates(cate_name) values ('路由器'),('交换机'),('网卡');
insert into goods_brands(brand_name) values ('海尔'),('清华同方'),('神舟');
```
> 在 goods 数据表中写入任意记录
```
insert into goods (name,cate_id,brand_id,price)
values('LaserJet Pro P1606dn 黑白激光打印机','12','4','1849');
```
> 查询所有商品的详细信息 (通过左右链接来做)
```
select * from goods left join goods_cates on goods.cate_id=goods_cates.id
inner join goods_brands on goods.brand_id=goods_brands.id
```
> 显示没有商品的品牌(通过右链接+子查询来做) -- 右链接
```
select * from goods right join goods_brands on goods.brand_id =goods_brands.id
```
> -- 子查询
```
select * from goods_brands where id not in (select DISTINCT brand_id from goods)
```
- Linux
- Linux 文件权限概念
- 重点总结
- Linux 文件与目录管理
- 2.1 文件与目录管理
- 2.2 文件内容查阅
- 文件与文件系统的压缩,打包与备份
- 3.1 Linux 系统常见的压缩指令
- 3.2 打包指令: tar
- vi/vim 程序编辑器
- 4.1 vi 的使用
- 4.2 vim编辑器删除一行或者多行内容
- 进程管理
- 5.1 常用命令使用技巧
- 5.2 进程管理
- 系统服务 (daemons)
- 6.1 通过 systemctl 管理服务
- Linux 系统目录结构
- Linux yum命令
- linux系统查看、修改、更新系统时间(自动同步网络时间)
- top linux下的任务管理器
- Linux基本配置
- CentOS7开启防火墙
- CentOS 使用yum安装 pip
- strace 命令
- Linux下设置固定IP地址
- 查看Linux磁盘及内存占用情况
- Mysql
- 关系数据库概述
- 数据库技术
- 数据库基础语句
- 查询语句(--重点--)
- 约束
- 嵌套查询(子查询)
- 表emp
- MySQL数据库练习
- 01.MySQL数据库练习数据
- 02.MySQL数据库练习题目
- 03.MySQL数据库练习-答案
- Mysql远程连接数据库
- Python
- python基础
- Python3中字符串、列表、数组的转换方法
- python字符串
- python安装、pip基本用法、变量、输入输出、流程控制、循环
- 运算符及优先级、数据类型及常用操作、深浅拷贝
- 虚拟环境(virtualenv)
- 网络编程
- TCP/IP简介
- TCP编程
- UDP编程
- 进程和线程
- 访问数据库
- 使用SQLite
- 使用MySQL
- Web开发
- HTML简介
- Python之日志处理(logging模块)
- 函数式编程
- 高阶函数
- python报错解决
- 启动Python时报“ImportError: No module named site”错误
- python实例
- 01- 用python解决数学题
- 02- 冒泡排序
- 03- 邮件发送(smtplib)
- Django
- 01 Web应用
- Django3.2 教程
- Django简介
- Django环境安装
- 第一个Django应用
- Part 1:请求与响应
- Part 2:模型与后台
- Part 3:视图和模板
- Part 4:表单和类视图
- Part 5:测试
- Part 6:静态文件
- Part 7:自定义admin
- 第一章:模型层
- 实战一:基于Django3.2可重用登录与注册系统
- 1. 搭建项目环境
- 2. 设计数据模型
- 3. admin后台
- 4. url路由和视图
- 5. 前端页面设计
- 6. 登录视图
- 7. Django表单
- 8. 图片验证码
- 9. session会话
- 10. 注册视图
- 实战二:Django3.2之CMDB资产管理系统
- 1.项目需求分析
- 2.模型设计
- 3.数据收集客户端
- 4.收集Windows数据
- 5.Linux下收集数据
- 6.新资产待审批区
- 7.审批新资产
- django 快速搭建blog
- imooc-Django全栈项目开发实战
- redis
- 1.1 Redis简介
- 1.2 安装
- 1.3 配置
- 1.4 服务端和客户端命令
- 1.5 Redis命令
- 1.5.1 Redis命令
- 1.5.2 键(Key)
- 1.5.3 字符串(string)
- 1.5.4 哈希(Hash)
- 1.5.5 列表(list)
- 1.5.6 集合(set)
- 1.5.7 有序集合(sorted set)
- Windows
- Win10安装Ubuntu子系统
- win10远程桌面身份验证错误,要求的函数不受支持
- hm软件测试
- 02 linux基本命令
- Linux终端命令格式
- Linux基本命令(一)
- Linux基本命令(二)
- 02 数据库
- 数据库简介
- 基本概念
- Navicat使用
- SQL语言
- 高级
- 03 深入了解软件测试
- day01
- 04 python基础
- 语言基础
- 程序中的变量
- 程序的输出
- 程序中的运算符
- 数据类型基础
- 数据序列
- 数据类型分类
- 字符串
- 列表
- 元组
- 字典
- 列表与元组的区别详解
- 函数
- 案例综合应用
- 列表推导式
- 名片管理系统
- 文件操作
- 面向对象基础(一)
- 面向对象基础(二)
- 异常、模块
- 05 web自动化测试
- Day01
- Day02
- Day03
- Day04
- Day05
- Day06
- Day07
- Day08
- 06 接口自动化测试
- 软件测试面试大全2020
- 第一章 测试理论
- 软件测试面试
- 一、软件基础知识
- 二、网络基础知识
- 三、数据库
- SQL学生表 — 1
- SQL学生表 — 2
- SQL查询 — 3
- SQL经典面试题 — 4
- 四、linux
- a. linux常用命令
- 五、自动化测试
- 自动化测试
- python 笔试题
- selenium面试题
- 如何判断一个页面上元素是否存在?
- 如何提高脚本的稳定性?
- 如何定位动态元素?
- 如何通过子元素定位父元素?
- 如果截取某一个元素的图片,不要截取全部图片
- 平常遇到过哪些问题?如何解决的
- 一个元素明明定位到了,点击无效(也没报错),如果解决?
- selenium中隐藏元素如何定位?(hidden、display: none)
- 六、接口测试
- 接口测试常规面试题
- 接口自动化面试题
- json和字典dict的区别?
- 测试的数据你放在哪?
- 什么是数据驱动,如何参数化?
- 下个接口请求参数依赖上个接口的返回数据
- 依赖于登录的接口如何处理?
- 依赖第三方的接口如何处理
- 不可逆的操作,如何处理,比如删除一个订单这种接口如何测试
- 接口产生的垃圾数据如何清理
- 一个订单的几种状态如何全部测到,如:未处理,处理中,处理失败,处理成功
- python如何连接数据库操作?
- 七、App测试
- 什么是activity?
- Activity生命周期?
- Android四大组件
- app测试和web测试有什么区别?
- android和ios测试区别?
- app出现ANR,是什么原因导致的?
- App出现crash原因有哪些?
- app对于不稳定偶然出现anr和crash时候你是怎么处理的?
- app的日志如何抓取?
- logcat查看日志步骤
- 你平常会看日志吗, 一般会出现哪些异常
- 抓包工具
- fiddler
- Wireshark
- 安全/渗透测试
- 安全性测试都包含哪些内容?
- 开放性思维题
- 面试题
- 字节测试面试
- 一、计算机网络
- 二、操作系统
- 三、数据库
- 四、数据结构与算法
- 五、Python
- 六、Linux
- 七、测试用例
- 八、智力/场景题
- 九、开放性问题
- python3_收集100+练习题(面试题)
- python3_100道题目答案
- 接口测试
- 接口测试实例_01
- python+requests接口自动化测试框架实例详解
- 性能测试
- 性能测试流程
- 性能测试面试题
- 如何编写性能测试场景用例
- 性能测试:TPS和QPS的区别
- jmeter
- jmeter安装配置教程
- Jmeter性能测试 入门
- PyCharm
- 快捷工具
- 1-MeterSphere
- 一、安装和升级
- 2- MobaXterm 教程
- 3-fiddler抓包
- 4-Xshell
- Xshell的安装和使用
- Xshell远程连接失败怎么解决
- 5-Vmware
- Vmware提示以独占方式锁定此配置文件失败
- Windows10彻底卸载VMWare虚拟机步骤
- VM ware无法关机,虚拟机繁忙
- VMware虚拟机下载与安装
- 解决VM 与 Device/Credential Guard 不兼容。在禁用 Device/Credential Guard 后,可以运行 VM 的方法
- VMware虚拟机镜像克隆与导入
- 6-WPS
- 1.WPS文档里的批注怎么删除
- 2.wps表格中设置图表的坐标
- 3. wps快速绘制数学交集图
- 7-MongoDB
- Win10安装配置MongoDB
- Navicat 15.x for MongoDB安装破解教程
- Apache
- apache层的账户权限控制,以及apache黑名单白名单过滤功能
- HTTP / HTTPS协议
- HTTP协议详解
- 代理
- 状态码详解
- HTTPS详解
- Selenium3+python3
- (A) selenium
- selenium自动化环境搭建(Windows10)
- 火狐firebug和firepath插件安装方法(最新)
- 元素定位工具和方法
- Selenium3+python3自动化
- 新手学习selenium路线图---学前篇
- 1-操作浏览器基本方法
- 2-八种元素定位方法
- 3-CSS定位语法
- 4-登录案例
- 5-定位一组元素find_elements
- 6-操作元素(键盘和鼠标事件)
- 7-多窗口、句柄(handle)
- 8-iframe
- 9-select下拉框
- 10-alert\confirm\prompt
- 11-JS处理滚动条
- 12-单选框和复选框(radiobox、checkbox)
- 13-js处理日历控件(修改readonly属性)
- 14-js处理内嵌div滚动条
- 15-table定位
- 16-js处理多窗口
- 17-文件上传(send_keys)
- 18-获取百度输入联想词
- 19-处理浏览器弹窗
- 20-获取元素属性
- 21-判断元素存在
- 22-爬页面源码(page_source)
- 23-显式等待(WebDriverWait)
- 24-关于面试的题
- 25-cookie相关操作
- 26-判断元素(expected_conditions)
- 27-判断title(title_is)
- 28-元素定位参数化(find_element)
- 29-18种定位方法(find_elements)
- 30- js解决click失效问题
- 31- 判断弹出框存在(alert_is_present)
- 32- 登录方法(参数化)
- 33- 判断文本(text_to_be_present_in_element)
- 34- unittest简介
- 35- unittest执行顺序
- 36- unittest之装饰器(@classmethod)
- 37- unittest之断言(assert)
- 38- 捕获异常(NoSuchElementException)
- 39- 读取Excel数据(xlrd)
- 40- 数据驱动(ddt)
- 41- 异常后截图(screenshot)
- 42- jenkins持续集成环境搭建
- 43- Pycharm上python和unittest两种运行方式
- 44- 定位的坑:class属性有空格
- 45- 只截某个元素的图
- 46- unittest多线程执行用例
- 47- unittest多线程生成报告(BeautifulReport)
- 48- 多线程启动多个不同浏览器
- (B) python3+selenium3实现web UI功能自动化测试框架
- (C) selenium3常见报错处理
- 书籍
- (D)Selenium3自动化测试实战--基于Python语
- 第4章 WebDriver API
- 4.1 从定位元素开始
- 4.2 控制浏览器
- 4.3 WebDriver 中的常用方法
- 4.4 鼠标操作
- 4.5 键盘操作
- 4.6 获得验证信息
- 4.7 设置元素等待
- 4.8 定位一组元素
- 4.9 多表单切换
- 4.10 多窗口切换
- 4.11 警告框处理
- 4.12 下拉框处理
- 4.13 上传文件
- 4.14 下载文件
- 4.15 操作cookie
- 4.16 调用JavaScript
- 4.17 处理HTML5视频播放
- 4.18 滑动解锁
- 4.19 窗口截图
- 第5章 自动化测试模型
- 5.3 模块化与参数化
- 5.4 读取数据文件
- 第6章 unittest单元测试框架
- 6.1 认识unittest