您的当前位置:首页正文

2021-04-24

2024-11-07 来源:个人技术集锦

MySQL的查询数据

1.单表查询

语法:
       select |字段列表|表达式 from 表名 [where 条件] [order by 字段列表]

说明:

select * from 表名(*相当于按照表中字段顺序罗列表中的所有字段)。

字段列表:当查询结果只是表中部分字段时,可将要显示的字段罗列出来,字段之间以逗号间隔。select 字段1,字段2 from 表名

表达式:可以是算术运算符也可以是数据库中的函数。select age+1 from student;(查询过程中使age列都加一并且出现)select length(字段名) from student;(length获取字符串的个数,单行函数,后面会说。)

where:指定查询过滤条件。

order by:对查询结果进行排序。

这些下面会有讲解。



 

create table student(
    id char(36) primary key,
    name varchar(8) not null,
    age int(3) default 0,
    mobile char(11),
    address varchar(150)
)
insert into student
values ('9b4435ec-372c-456a-b287-e3c5aa23dff4','张三',24,'12345678901','北京海淀');
insert into student
values ('a273ea66-0a42-48d2-a17b-388a2feea244','李%四',10,'98765432130',null);
insert into student
values ('eb0a220a-60ae-47b6-9e6d-a901da9fe355','张李三',11,'18338945560','安徽六安');
insert into student
values ('6ab71673-9502-44ba-8db0-7f625f17a67d','王_五',28,'98765432130','北京朝阳区');
insert into student
values ('0055d61c-eb51-4696-b2da-506e81c3f566','王_五%%',11,'13856901237','吉林省长春市宽平区')    

where:指定查询过滤条件。(需要充分理解,最好自己在软件上一个个尝试慢慢体会)
like:进行数据模糊查询
%:匹配0次或多次      

例子:

select * from student where name like '张%'   会导致出现张三和张李三;前面%代表匹配一次,后面%代表匹配两次;

select * from student where name like '%李%’  这个前面%可以理解为李的前面有0到无穷个字,这个后面%可以理解为李的后面面有0到无穷个字,而这行代码指的是名字中含有李的学生信息。
_:只匹配1次      

如果你前面的%理解了,那这个_就不是问题。

   select * from student where name like '张_’     只会出现张三的学生信息

但如果人的名称里出现了% _号该如何查询呢?

escape:取消%或_字符的通配符特性

例子:

#查询姓名中含有%字符的学生信息
select * from student where name like '%#%%' escape ‘#’(并不是非要填#,也可以填其它字母或者字符。可以理解为取消了#后面第一个%的特性)
#查询姓名中含有_字符的学生信息
select * from student where name like '%$_%' escape ‘$’(并不是非要填$,也可以填其它字母或者字符。可以理解为取消了#后面第一个%的特性)
#查询姓名以%%结尾的学生信息
select * from student where name like ‘%A%A%' escape ‘A’;表明了escape‘A’是取消了所有A后面第一个%或_的特性.
 注意:
escape后面单引号中只能是单个字符;
escape后面可以是字母、#、$、,、\等字符,不能是_;

逻辑条件:and、or

between 下限 and 上限:等同于“(字段名>=下限) and (字段名<=上限)”[小的数在前面,大的数在后面,包括边界值]

#查询年龄在10~28之间的学生信息
select * from student where age between 10 and 28;
#上面SQL语句等效于该SQL语句
select * from student where age >= 10 and age<=28;

关系条件:=、!=、<、=<、>、>=等(就是where后面的限制条件,这个和C语言不同,=就是=,不是赋值的意思,不需要写==)

in(value1,value2,value3......valuen):等同于“ 表名1 = value1 or表名2 = value2 or 表名3 = value3...... or 表名n = valuen ”

select * from student where age in(10,17,24);
#上面SQL语句等效于下面语句
select * from student where age = 10 or age=17 or age = 24;

null :包括is null 和 is not null(is null不能写成 = null,同样,is not null不能写成!=null)

order by:对查询结果进行排序。(asc升序,desc降序,asc为默认可以省略)

分为两种。一种是单列排序,另一种是多重排序。

单列排序:以一个字段对查询结果进行排序,最终显示经过一次排序后的查询结果

用字段排序

例子:

select id,name,age,mobile,address from student order by age desc;

用字段别名排序

例子:

select id,name,age as stu_age,mobile,address from student order by stu_age desc;

多重排序:也称多列排序,即先以一个字段对查询结果进行排序,然后在这个排序的基础上再对另一个字段进行排序,最终显示经多次排序后的查询结果;

select * from student order by age desc,name asc;(首先会根据age降序排列,再根据相同的age,比对name进行升序排列)

distinct:去除相同的行(“相同的行”指不同行之间的相同列中的数值相同)
例如:
select distinct age from student;
select distinct age,name from student;
注意:该关键字必须紧跟select关键字的后面,不然无法运行。即如下写法是错误的: select age,distinct name from student

 

算术表达式

MySQL数据库中的算术运算符包括+、-、*和/,其中/运算符的结果为浮点类型的数值
       例如:select age + 1 age from student;
MySQL数据库中没有取余运算符,如果要对数据进行取余运算只能借助数据库mod(x,y)来实现,其中x为被除数,y为除数
       例如:select mod(1,3) as result from dual;

 

dual表为MySQL数据库伪表,在没有目标表的情况下,用来使select语法完整(select子句必须包括from子句)。
例子:

select 1+1 from dual;

2.多行函数(组函数忽略空值,组函数默认考虑重复值,下面有相对处理方法,ifnull函数和distinct)

常用组函数:

avg(字段名):求平均值

max(字段名):求最大值

min(字段名):求最小值

sum(字段名):求和

count(字段名):求行数,如果使用*则不会忽略空值的行

stddev(字段名):求标准差

variance(字段名):求方差

count、max和min组函数操作的数据的数据类型可以是char、varchar、int或date,但不能为clob;avg、sum、stddev和varlance仅能用在数字类型的数据上。

select count(name) from student;#3,student表中有一条数据中的name为空

select count(distinct name) from student;#2,student表中有一条数据中的name为空,有两条数据name的值重复

select count(ifnull(name,' ')) from student;#4, 将name为空的值置为1个空格

select count(*) from student;#4,*不会忽略空值的行 (因为*代表了所有字段,而主键不为0,则 每行不可能全为空值)

group by

group by用于将表中数据划分为若干个组,group by后面用于指定分组的依据

再给你一串代码

create table student(
id char(1) primary key,
name varchar(8),
sex char(2) default '男' ,
age int(3) default 0
)
 
insert into student values ('1','王明','男',18);
insert into student values ('2','孙丽','女',17);
insert into student values ('3','王明','男',27);
insert into student (id,sex,age) values ('4','男',27);

运行完后

 select count(id) from student group by sex 会根据sex进行分组,但是此时只有数字没有特殊含义,我们需要再count(id)前加上sex即可清楚知道男女分别人数。

select name from student group by name 会根据name分组

select name,sex from student group by name,sex     先根据name分组,name相同再根据sex分组,与前面的order by类似。

注意:

如果select语句中使用group by进行了分组,则select子句中只可以有组函数和分组字段,不能含有其他字段,否则SQL语句报错;

如果group by子句后面跟着order by子句,则order by子句用于排序的字段必须是组函数或分组字段;

如果select语句中含有where、order by,那么group by需放在where之后order by之前,即先获取符合where条件的“有效”数据,再依据group by对数据进行分组,最后再排序;

 

having的由来:

where后面不能使用多行函数,只能使用单行函数和字段,having关键字弥补了这一不足:having子句用于对分组结果进行约束

 select name from student group by name having count(name)>1

注意:

having子句一般和group by子句一起使用,MySQL数据库也可以单独使用,但是Oracle数据库不允许单独使用

having子句必须放在group by子句之后,order by子句之前

3.

多表查询

多个表关联查询需要依据多表之间列关系将其连接起来,这种连接方式分为三种:内连接(inner join)、外连接(outer join)及交叉连接(cross join)

多表查询并不难理解,难的是你如何写出这段代码。我首先给你一段代码,你再去尝试。

create table user_info(
      id int(2) primary key,
      user_name varchar(12) unique,
      password varchar(15) not null,
      real_name varchar(8) not null,
      age int(3)
);

create table address(
      id int(2) primary key,
      user_id int(2) not null,
      real_name varchar(8),
      mobile char(11),
      address varchar(150)
);

insert into user_info values(1,'浅唱灬幸福','8912@321','王晓明',12);
insert into address values(1,1,'王小明','15516472282','山西太原');
insert into address values(2,1,'王鑫','18404905139','山西大同');
insert into address values(3,1,'任建','15333021730','山西晋城');
 
insert into user_info values(2,'ぅ浮生若梦〤','56701wz','王楠',36);
insert into address values(4,2,'王楠','15010303314','北京海淀');
insert into address values(5,2,'赵婕','18435224278','山西长治');
 
insert into user_info values(3,'街角の风铃','27w4921','李晓飞',9);

insert into address values(6,6,'刘倩','13159775555','吉林长春');

内连接:

如果依据多个表之间列关系进行内连接,查询结果集仅包括满足连接条件的数据行。内连接分为等值连接、不等值连接以及自然连接,其中等值连接最为常见。
等值连接:在连接条件中使用等号(=)运算符比较被连接列的列值是否相等,分显式等值连接和隐式等值连接:

显式等值连接:(别名看不懂,上面有讲解,ui.*指的是ui的全部字段;我建议你先看隐式等值连接再看显式等值连接,这样比较容易理解。显式等值连接的ui.*,addr.*顺序可以换,后面也可以换,只不过把列的标题换了)
              select ui.*,addr.* from user_info ui inner join address addr on ui.id = addr.user_id;
隐式等值连接:
              select ui.*,addr.* from user_info ui,address addr where ui.id = addr.user_id;

内连接会了,外连接自然会了,只不过把inner换成left。

外连接:

如果依据多表之间列关系进行外连接,查询结果集不仅仅包括满足on连接条件的数据行,还包括不满足on连接条件的数据行。
左外连接(left [outer] join):返回的结果集中不仅包含表之间满足on连接条件的全部数据行,还包含左表(“left [outer] join”关键字左边的表)不满足on连接条件的数据行;
       select ui.*,addr.* from user_info ui left join address addr on ui.id = addr.user_id;

交叉连接:(没必要理解,没什么实际用处,想知道就去查查笛卡尔积)

左表(“cross join”关键字左边的表)中的每一行与右表(“cross join”关键字右边的表)中的所有行组合,交叉联接的结果是一个笛卡尔积。
       select ui.*,addr.* from user_info ui cross join address addr;

 

 

 

 

显示全文