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可以大写,可以小写,也可以不写,但是建议用大写,这样一眼就可以看出设置了别名。
网友评论