走向DBA之SQL语句(DQL)

select 查看

一、作用:

获取MySQL中的数据行信息

二、单独使用select

2.1获取参数信息

语法:select @@xxx
mysql> select @@port;      获取端口号                                              
+--------+
| @@port |
+--------+
|   3306 |
+--------+
1 row in set (0.00 sec)

2.2模糊匹配获取参数信息

语法:like '%内容%'
mysql> show variables like 'wait_%'; 查看所有参数信息中的以wait_开头的参数
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout  | 28800 |
+---------------+-------+
1 row in set (0.00 sec)

2.3调用函数

mysql> select now();          查看当前时间
mysql> select version();      查看MySQL版本
mysql> select databse();      查看当前在哪个库
......

三、SQL92便准语法

3.1select 语法执行顺序(单表)

select  开始  --->
from    --->
where   --->
group by   --->
select 后执行条件   --->
having   --->
order by   --->
limit

3.2select语句具体应用及人类可读解释说明

单表子句from

1.from    数据来自哪里
select * from world.city;          查看world库下city表的所有数据信息

select name,population from city;  查看city表的name和population列

单表子句where

2.where 匹配条件:(等值查询=,不等值查询<,>,<=,>=,<>,)
                  (模糊匹配 like,逻辑连接符号:and,or)
等值匹配
select * from teacher where name='oldboy' ;  查看teacher表中name列等于oldboy的行

不等值匹配
select * from sc where score>80;             查看sc表中score列大于80的所有行

模糊匹配
select * from teacher where name like '王'%; 查看teacher表中name列以'王'开头的所有行

#注意,模糊匹配%尽量放结尾,也就是匹配以什么开头的,%放在开头或者两头都放,虽然可以执行,但是数据太大的时候,效率很低!

逻辑连接符匹配
select * from sc where score>60 and score<80; 查找成绩大于60同时小于80的(and逻辑连接符,需要满足两边条件)
select * from sc where score>90 or score<20; 查找成绩大于90或者小于20的(or逻辑连接符,满足一个条件即可输出,两个条件都满足,都输出)

group by + 常用聚合函数

group by 可以理解为根据 by后面的条件进行分组(站队)方便统计,by后面跟一个列或多个列
介绍一些常用聚合函数:
AVG()           平均值
COUNT()         计数
SUM()           数值之和
MAX()           最大值
MIN()           最小值
GROUP_CONCAT()  一行显示查到的内容
group by 配合聚合函数具体用法:
统计每个学生的总成绩
select name,sum(score) from sc group by nob;
      名字列  成绩之和       sc表    按照nob(序列号)排队
拿什么站队?
nob序列号(主键,或者出现在select后,或者出现在函数里)
拿什么统计?
学生名,name
统计的是什么?
成绩总和
这里不太好理解,下边写到多表连接查询的时候,还会说明

having

说明:在select查看匹配条件之后,再做处理,相当于linux下的管道

统计中国每个省的总人数,且纸打印小于一百万的。
SELECT district,SUM(Population)
FROM city
WHERE countrycode='chn'
GROUP BY district
HAVING SUM(Population) < 1000000 ;

order by

理解为排序

查看中国每个省的总人数,且从大到小排序
SELECT  district ,SUM(population) FROM city 
WHERE countrycode='CHN'
GROUP BY district 
ORDER BY SUM(population) DESC  ;  
默认时从小到大排序,加desc时从大到小排序

limit

理解为截取几行,和linux下cut -c差不多

select *
from world.city
where countrycode='CHN' 
order by population desc
limit 10;
显示十行

select *
from world.city
where countrycode='CHN' 
order by population desc
limit 5,5;
跳过前五行,显示五行(从第六行开始显示,显示五行。就是第六行到第十行)

limit m,n   跳过m行,显示n行

四、多表连接

4.1什么时候用?

需要查询的信息来自不同的表时,需要使用多表连接的方法来查询

4.2怎么去多表连接查询?

4.2.1传统的连接,基于where条件

第一步:找表与表之间的关系列
第二部:排列查询条件
实施代码:

查人口数量小于一千人的城市,所在国家的国土面积(城市名,国家名,国土面积)
select city.name,country.name,country.surfacearea
from city,country
where city.countrycode = country.code
and city.population<1000
本方法现在很少使用,因此不过多阐述

4.2内连接(多表连接查询的重点*****)

语法介绍:

关键词: join on
1.找到表与表之间的关系列    A表的x列,B表的y列
2.将两个表放在join两边     A join B
3.将关联条件放在on后边     on A.x=B.y
4.将所有的查询条件进行罗列 

select A.m,B.n
from  
A  join  B
on A.x=B.y
where 
group by 
order by 
limit

可以理解为,join将两表的关系列(内容相同列)为条件,把两表合为一个表
image.png

举例说明:

clipboard.png
--- 2. 查询oldguo老师和他教课程名称
SELECT teacher.tname ,course.cname
FROM teacher 
JOIN course 
ON teacher.tno=course.tno
WHERE teacher.tname='oldguo';
解释说明:select 后边为要查询的内容来自xx表的xx列(老师名字列和课程名称列),join前后为信息来源的两张表,
on后边写的两张表的关系列(内容相同),查询条件是teacher表tname列等于oldguo的行。
查每一科成绩的总成绩
select course.cno,course.cname,sum(score.score)
from
course join score
on course.cno=score.cno
group by score.cno;
解释说明:sekect后边写的是要查询的数据来自课程表下的顺序列,课程表下的课程名称列,和成绩表下的成绩列并求和。
join前后为信息来源的两张表,on后边是两张表的数据关联列,group by ,按照成绩的序列号(主键站队)
--- 4. 查询oldguo老师教的学生姓名列表
SELECT teacher.tname,GROUP_CONCAT(student.sname)
FROM teacher 
JOIN course
ON teacher.tno = course.tno
JOIN score
ON course.cno = score.cno
JOIN student 
ON score.sno = student.sno
WHERE teacher.tname='oldguo'
GROUP BY teacher.tname;
--- 5. 查询所有老师教的学生姓名列表
SELECT teacher.tname,GROUP_CONCAT(student.sname)
FROM teacher 
JOIN course
ON teacher.tno = course.tno
JOIN sc
ON course.cno = sc.cno
JOIN student 
ON sc.sno = student.sno
GROUP BY teacher.tno;
--- 6. 查询oldboy老师教的不及格学生的姓名
SELECT teacher.tname,GROUP_CONCAT(student.sname)
FROM teacher 
JOIN course
ON teacher.tno = course.tno
JOIN score
ON course.cno = score.cno
JOIN student 
ON score.sno = student.sno
WHERE teacher.tname='oldguo'
and score.score<60
GROUP BY teacher.tname;
--- 7. 统计zhang3,学习了几门课
select student.sname,COUNT(course.cname)
from
student join score
on
student.sno=score.sno
join course
on
score.cno=course.cno
where student.sname='zhang3'
group by student.sno;
--- 8. 查询zhang3,学习的课程名称有哪些?
select student.sname,GROUP_CONCAT(course.cname)
from
student join score
on
student.sno=score.sno
join course
on
score.cno=course.cno
where student.sname='zhang3'
group by student.sno;
--- 9. 查询oldguo老师教的学生名.
SELECT teacher.tname,GROUP_CONCAT(student.sname)
FROM teacher 
JOIN course
ON teacher.tno = course.tno
JOIN score
ON course.cno = score.cno
JOIN student 
ON score.sno = student.sno
WHERE teacher.tname='oldguo'
GROUP BY teacher.tname;
--- 10.查询oldguo所教课程的平均分数
select teacher.tname,AVG(score.score)
from
teacher join course
on
teacher.tno=course.tno
join score
on
course.cno=score.cno
where teacher.tname='oldguo'
group by teacher.tname;
--- 11.每位老师所教课程的平均分,并按平均分排序
select teacher.tname,course.cname,AVG(score.score)
from
teacher join course
on teacher.tno=course.tno
join score
on course.cno=score.cno
group by teacher.tno,course.cno
order by AVG(score.score);

4.3外连接:

外连接分:

左外连接 即:left join          
右外连接 即: right join
注意:需要把where换成and(如果不换的话,不会起到外连接的效果,只会让左表(或右表)当作驱动表,助力查询)
解释:拿左外连接来讲,在正常取出两表关联列之外,把左表的全部数据也取出来,那么右边的那个表没有这些数据怎么办呢?嘿嘿,用null填充。注意,这种外连接的方法,不仅需要加left(一般都加这个)或者right之外,同时需要把where改成and,才算真正的左外连接。

示例:

正常连表查询:
mysql> select teacher.tname,course.cname
    -> from teacher join course
    -> on teacher.tno=course.tno
    -> where  teacher.tname='oldguo';
+--------+-------+
| tname  | cname |
+--------+-------+
| oldguo | mysql |
+--------+-------+
1 row in set (0.00 sec)
左外连接连表查询:
mysql> select teacher.tname,course.cname
    -> from teacher left join course
    -> on teacher.tno=course.tno
    -> and  teacher.tname='oldguo';
+--------+-------+
| tname  | cname |
+--------+-------+
| oldguo | mysql |
| oldboy | NULL  |  ------->看到了吧,把左表的全部列打印出来了,右边以null填充。
| hesw   | NULL  |
+--------+-------+
3 rows in set (0.00 sec)

补充语句:

distinct() 对列去重

select distinct(cno) from score;
合并(去重)cno列

效果:

去重前:
mysql> select count(name) from world.city;
+-------------+
| count(name) |
+-------------+
|        4079 |
+-------------+
1 row in set (0.08 sec)
去重后:
mysql> select count(distinct(name)) from world.city;
+-----------------------+
| count(distinct(name)) |
+-----------------------+
|                  3998 |
+-----------------------+
1 row in set (0.00 sec)

别名:AS

说明:和linux命令行设置别名差不多.

1.表别名:

在这里,别名只能在本次select语句中使用,一般别名在from后设置,设置之后,整条select语句都可以运用别名。
用法:from 表名 AS 别名

不加别名:

select teacher.tname,group_concat(student.sname)
from
teacher join course
on teacher.tno=course.tno
join score
on course.cno=score.cno
join student
on score.sno=student.sno
where teacher.tname='oldguo' and score.score<60
group by teacher.tno
添加别名:
select te.tname,group_concat(st.sname)
from
teacher AS te join course AS co
on te.tno=co.tno
join score AS sc
on co.cno=sc.cno
join student AS st
on sc.sno=st.sno
where te.tname='oldguo' and sc.score<60
group by te.tno;
#建议:一般别名设置为表名的前两个字符,简单且不易弄混

2.列别名:

作用:打印输出的时候,把表头更改为你设置的别名

不加别名

mysql> select count(distinct(name)) from world.city;
+-----------------------+
| count(distinct(name)) |
+-----------------------+
|                  3998 |
+-----------------------+
1 row in set (0.01 sec)

添加别名:

mysql> select count(distinct(name)) AS n from world.city;
+------+
| n    |
+------+
| 3998 |
+------+
1 row in set (0.00 sec)
注意:设置别名的AS可以大写,可以小写,也可以不写,但是建议用大写,这样一眼就可以看出设置了别名。

你可能感兴趣的:(走向DBA之SQL语句(DQL))