MySQL查询

开始下面的MySQL具体使用语法之前,先解决困扰我很久的一个问题:

通常说的MySQL,Oracle,SQL Server等等,都是数据库管理工具,只是用来管理数据的。在实际的开发过程中,数据通常是通过Web提供的数据驱动来连接数据库进行增删改查的。

以MySQL为例,在Mysql下的data文件夹下对应有创建的数据库和表数据,

所以,其实,数据其实是存储在不熟数据库的机器的硬盘中的。

 

 

 

.sql文件:

一: .sql结尾的文件可以直接导入到mysql客户端,执行该文件中的sql语句。

sql文件中的注释以--开头;

连接数据库:

mysql -uroot -p  回车然后输入密码

创建数据库:

==> create database 库名 charset=utf8;

使用数据库:

==> use 库名;

显示当前使用的数据库是哪个:

==> select databases();

创建数据表:

格式:   

create table 表名(

字段名1    类型  约束 ,

字段名2   类型  约束 ,

......

字段名1    类型  约束 

);

create table students(
  id int unsigned primary key auto_increment not null,
  name varchar(20) default '',
  age tinyint unsigned default 0,
  height decimal(5,2),
  gender enum('男','女','中性','保密') default '保密',
  cls_id int unsigned default 0,
  is_delete bit default 0
);

create table classes(

  id int unsigned auto_increment primary key not null,

  name varchar(30) not null

);

以查看创建某表时的语句;

==>show create table 表名; 

插入数据:(一次插入多条数据)

insert into students values
(0,'小明',18,180.00,2,1,0),
(0,'小月月',18,180.00,2,2,1),
(0,'彭于晏',29,185.00,1,1,0),
(0,'刘德华',59,175.00,1,2,1),
(0,'黄蓉',38,160.00,2,1,0),
(0,'凤姐',28,150.00,4,2,1),
(0,'王祖贤',18,172.00,2,1,1),
(0,'周杰伦',36,NULL,1,1,0),
(0,'程坤',27,181.00,1,2,0),
(0,'刘亦菲',25,166.00,2,2,1),
(0,'金星',33,162.00,3,3,1),
(0,'静香',12,180.00,2,4,0),
(0,'郭靖',12,170.00,1,4,0),
(0,'周杰',34,176.00,2,5,0);

往classes表中插入数据:

insert into classes values (0,"python_01期"),(0,"python_02期");

查询语句:

1: 普通查询

1.1:查询所有字段:

select * from students;

select * from classes;

1.2:查询指定字段:

select name,age from students;

1.3:给字段起别名

select name as 姓名,age as 年龄 from students;

1.4:表名.字段名

select students.name ,students.age from students;

select s.name ,s.age from students as s;

1.5:去重查询

select distinct name from students;

2: 条件查询(where;使用小括号提高运算优先级)

2.1:比较运算符查询

2.1.1: 大于(>) 查询

SELECT * FROM students where age >18;

2.1.2: 小于(<) 查询

SELECT * FROM students where age <18;

2.1.3: 大于等于(>=) 查询

2.1.4: 小于等于(<=) 查询

2.1.5: 不等于(!=) 查询

2.2:逻辑运算符查询

2.2.1: and

SELECT * FROM students where age>18 and age <28;

2.2.1: or

SELECT * FROM students where age>18 or height>=180;

2.2.1: not

不在   18岁以上的女性,select * from students where not(age>18 and gender='女');

年龄不是小于或者等于18,并且是女性,select * from students where (not age<=18) and gender ='女';

2.3:模糊查询(like[%代替一个或者多个字符; _代表一个字符],  rlike[正则表达式]) : 效率比较低

2.3.1: like

查询姓名中以小开头的: select * from students where name like '小%';

查询姓名中包含小字的: select * from students where name like '%小%';

查询名字有2个字的学生的信息:select * from students where name like '__';

查询名字 至少有2个字的学生的信息:select * from students where name like '__%';

2.3.2: rlike

查询姓名中以周开头的人: select * from students where name rlike '^周.*';

查询姓名中以周开头并且以伦结尾的人: select * from students where name rlike '^周.*伦$';

2.4:范围查询

2.4.1: in(表示在一个非连续的范围)

查询年龄为,18,24,12的人: SQL1:select name,age from students where age=18 or age=24 or age=12;  ==》不推荐

                                             SQL2:  select name,age from students where age in (18,24,12); 推荐

2.4.2: not in(表示不在一个非连续的范围)

查询年龄不为,18,24,12的人: select name,age from students where age not in (18,24,12); 

2.4.3: between ....and ....(表示在一个连续的范围,包含两边的范围)

查询年龄为,18,24,12的人: select name,age from students where age between 18 and 28;

2.4.4: not between ....and ....(表示不在一个连续的范围,包含两边的范围)

查询年龄不为,18,24,12的人: select name,age from students where age not between 18 and 28;

2.5:空判断

a=None  =>  a没有指向

a=''         =>a指向一个字符串对象,不过字符串为空,是有空间的。

2.5.1: is null(判断为空)

查找身高字段为空的人的名字和年龄身高信息: select name,age,height from students where height is null;

2.5.2: not null(判断不为空)

查找身高字段为空的人的名字和年龄身高信息: select name,age,height from students where height is not null;

 

2.6:聚合函数

2.6.1: 计数(count)

select count(*) as 女性人数 from students where gender='女';

2.6.2: 最大值

select max(age) from students ;

2.6.3: 最小值

select min(age) from students ;

2.6.4: 求和

select sum(age) from students ;

2.6.5:平均值

select avg(age) from students ;

select sum(age)/count(*) from students ;

2.6.6: 四舍五入

round(原来的数字,x表示小数位数)

求年龄平均值,并且只保留两位小数: select round(sum(age)/count(*),2) from students ;

2.7:分组: group by

2.7.1:group by

求不同性别下的人数;

select gender,count(*) from students group by gender;

==> 此处的count(*) 是对分组后的每组数据进行统计计算,不是对原数据进行计算;如果多重分组,写为:group by A, B

==>此处的count(*) 可以换成前面的聚合函数;

2.7.2:group_concat

查询同种性别的姓名:select gender,group_concat(name) from students group by gender;

==> group_concat 中也可以输出字符串

select gender,group_concat(name,"_",age,"_",height) from students group by gender;

==> group_concat(列名) =》可以显示该分组下对应的该列的所有的值:

 

2.7.3:where:是对原表进行条件限制,放在group by的前面

 求男性的人数:select gender,count(*) from students where gender='男' group by gender;

                          select gender,count(*) from students group by gender having gender='男';

2.7.4:having: 对分组的结果进行过滤,不能单独使用,使用时要放在group by的后面

查询平均年龄超过30岁的性别,以及名字,该性别组的平均年龄  :select gender,group_concat(name),avg(age) from students group by gender having avg(age)>30;

查询每种性别人数超过2的人员信息:select gender,group_concat(name) from students group by gender having count(*)>2;

2.8:排序: order by

升序排序: by asc, 默认可以省略asc

降序排序:by desc

2.8.1:orderby,单个字段

如果不指定order by 什么,sql语句默认是按照主键排序:

==> select * from students where (age between 18 and 34) and gender='男' order by age;

2.8.2:orderby,多个字段

order by 字段1 asc/desc, 字段2 asc/desc

==> 只有前面一个条件对应有相同的值,那么才会继续按照条件2排序,

==> 如果条件1对应的没有相同的值,那么条件2其实没有意义。

==> select * from students where (age between 18 and 34) and gender='女' order by height desc,id desc;

select gender,count(*) from students group by gender;

==> 此处的count(*) 是对分组后的每组数据进行统计计算,不是对元数据进行计算;

==》如果SQL语句中有group by, 那么select后面要显示的信息一定是对分组后的数据的处理。

======> order by 后面可以直接跟列的别名

2.9:分页: limit

==> 如果SQL语句中要使用limit,那么limit一定要放在SQL语句的最后。

2.9.1:limit 数字

限制查询两条结果:

==> select * from students where gender='女' limit 2;

2.9.2:limit 数字1[要开始显示数据位置的下标,整体下标是从0开始,具体要显示的开始数据的下标看具体的查询要求],数字2[要显示的数据的条数]

限制查询5条结果,从下标为2开始,即从第三个数开始:

==> select * from students where gender='女' limit 2,5;

规律:limit (第N页-1)*每页个数, 每页个数.

==> 但是不能直接将公式放入SQL语句,SQL语句不识别.

在SQL Server中可以使用top:查询前N条数据。

SELECT TOP N * FROM TABLE1

3:连接查询

 

select * from students inner join classes => 这个SQL语句语法上是没问题的,这个语句的意思是:

每显示students中的一条数据,都要把classes中的数据全都显示一遍。

 

3.1:inner join:   内连接(相关联的表里都有数据才会显示)

显示全部同学以及班级信息

==> select * from students inner join classes on students.cls_id=classes.id;

显示全部同学以及对应的班级名

==> 将班级名字放在第一列:  select c.name, s.* from students as s inner join classes as c on s.cls_id=c.id;

==> select students.*,classes.name from students inner join classes on students.cls_id=classes.id;

给表取别名(查询结果和上个SQL语句是一模一样的)

==> select s.*,c.name from students as s inner join classes as c on s.cls_id=c.id;

查询 有能够对应班级的学生以及班级的信息,按照班级, 学生ID排序

==》select s.*,c.name from students as s inner join classes as c on s.cls_id=c.id order by c.name;

3.2:left join  左连接: 哪个表在左边,以哪个表为基准,左边的表在右边的表中找不到数据的,就显示null

显示全部同学,以及其对应的班级信息

==> select * from students as s left join classes as c on s.cls_id=c.id;

 

 

 查询没有对应班级信息的学生:巧妙使用having(having是对查询到得结果集进行二次过滤)

==》 select * from students as s left join classes as c on s.cls_id=c.id having c.id is null;

也可以使用where: 从原表里做条件判断,用where

==》select * from students as s left join classes as c on s.cls_id=c.id where c.id is null;

4:自关联

比如表里存储:

省份 ID   省份名称    市ID,市区名称,以及区信息,等等

查询所有的省:

select * from table where 市ID  is null;

查询山东省有多少市:

思路1: 可以先查询青岛市ID(select Id from table where 省份名称="山东"), 然后以此ID作为条件再查: select * from table where 市区ID = 前面查到的ID;

方法2:将一张表作为2张表来使用

select * from areas as province inner join areas as city on city.pid=province.aid having province.atit ="山东省"

 

方法3, 子查询:

5:子查询

查询身高最高的学生的信息:

select * from students where height = (select max(height) from students)

B站UP主的课程视频:https://www.bilibili.com/video/BV1zJ411M7TB/?spm_id_from=autoNext

 

删除数据:

delet from tablename where 条件;

更新数据:

update tablename set columnname=value;

插入数据:

insert into tablename set  (列名1,列名2...) values(value1,value2...)

 

总结:

有时候一个查询要求可以用不同的SQL语句来实现,但是不同的是,不同的SQL语句的执行效率不同。

关联询的查询效率要高于子查询。

 

 

数据库设计:

遵循一些规则:

第一范式:强调列的原子性,即列不能再拆分成其他几列。

第二范式:必须要有主键(主键可以为多列),并且除主键外的字段都必须全部 直接 依赖于主键

。。。。。。等等

 

 

重点函数的用法:

===>limit:

limit n : 表示要显示出几条数据。

limit m,n: 表示从第m+1条数据开始查询,显示n条数据;  =》默认其实从第1条开始查询,第一条数据下标是0;

===>distinct: 去重

distinct(列名)

 

日期函数的用法: 以下函数分别获取日期中的天,月,年

DAY()

MONTH()

YEAR()

posted @ 2021-08-13 00:07  晨义  阅读(433)  评论(0)    收藏  举报