Mysql的DQL语句
- 十、Mysql的DQL语句
- select的查询
- 一、查看系统参数
- 二、select常用函数
- 三、select的单表查询
- 1、from子句
- 2、where子句
- 2.1 where配合等值查询
- 2.2where配合比较操作符(> < >= <= <>)
- 2.3where配合逻辑运算符(and or )
- 2.4where配合模糊查询
- 2.5where配合in语句
- 2.6where配合between and
- 3、group by + 常用聚合函数
- 4、having
- 5、order by + limit
- 6、distinct:去重复
- 四、联合查询--union all
- 五、别名
- 六、join 多表连接查询
十、Mysql的DQL语句
DQL(Data QueryLanguage)语句也就是select查询语句。
select的查询
一、查看系统参数
select @@xxx 查看系统参数,该参数一般为my.cnf中定义的参数
案例:
SELECT @@port;
查看mysql端口号
SELECT @@basedir;
查看mysql的程序目录
SELECT @@datadir;
查看mysql的数据目录
SELECT @@socket;
查看mysql的socket路径
SELECT @@server_id;
查看mysql的server_id号
二、select常用函数
SELECT NOW();
查看时间
SELECT DATABASE();
查看当前所有数据库
SELECT USER();
查案当前是使用那个用户登录数据库
SELECT CONCAT("hello world");
打印hello world,concat函数长用户拼接列信息
SELECT CONCAT(USER,"@",HOST) FROM mysql.user;
在mysql.user表中查看user和host信息,并以user@host的方式显示
SELECT GROUP_CONCAT(USER,"@",HOST) FROM mysql.user;
把查询到的结果横向显示,列转行
https://dev.mysql.com/doc/refman/5.7/en/func-op-summary-ref.html?tdsourcetag=s_pcqq_aiomsg
mysql函数地址
三、select的单表查询
select命令执行的顺序
select from where “group by” having “order by” limit
实验数据使用的world.sql数据库
[world]>show tables;
+-----------------+
| Tables_in_world |
+-----------------+
| city |
| country |
| countrylanguage |
+-----------------+
1、from子句
语句格式
SELECT 列1,列2 FROM 表
SELECT * FROM 表 (不建议在生产环境使用)
例子:
1)查询stu中所有的数据(不要对大表进行操作)
use school;
select * from stu;
2)查询stu表中,学生姓名和入学时间
use school;
select sname,intime from stu
2、where子句
语句格式
SELECT col1,col2 FROM TABLE WHERE colN 条件;
2.1 where配合等值查询
查询中国(CHN)所有城市信息
SELECT * FROM city WHERE countrycode='CHN';
查询北京市的信息
SELECT * FROM city WHERE NAME='peking';
查询甘肃省所有城市信息
SELECT * FROM city WHERE district='gansu';
2.2where配合比较操作符(> < >= <= <>)
<>表示为不等于!=
查询世界上少于100人的城市
SELECT * FROM city WHERE population<100;
2.3where配合逻辑运算符(and or )
中国人口数量大于500w
SELECT * FROM city WHERE countrycode='CHN' AND population>5000000;
中国或美国城市信息
SELECT * FROM city WHERE countrycode='CHN' OR countrycode='USA';
SELECT * FROM city WHERE countrycode IN ('CHN','USA');
2.4where配合模糊查询
查询省的名字前面带guang开头的
SELECT * FROM city WHERE district LIKE 'guang%';
注意:%不能放在前面,因为不走索引.
2.5where配合in语句
中国或美国城市信息
SELECT * FROM city WHERE countrycode IN ('CHN' ,'USA');
2.6where配合between and
查询世界上人口数量大于100w小于200w的城市信息
SELECT * FROM city WHERE population >1000000 AND population <2000000;
SELECT * FROM city WHERE population BETWEEN 1000000 AND 2000000;
3、group by + 常用聚合函数
group by:根据 by后面的条件进行分组,方便统计,by后面跟一个列或多个列
常用聚合函数
max() :最大值
min() :最小值
avg() :平均值
sum() :总和
count() :个数
group_concat() : 列转行
例子1:统计世界上每个国家的总人口数.
USE world;
SELECT countrycode,SUM(population) FROM city GROUP BY countrycode;
例子2: 统计中国各个省的总人口数量
USE world;
SELECT distric,SUM(population) FROM city WHERE countrycode="CHN" GROUP BY distric;
例子3:统计世界上每个国家的城市数量
USE world;
SELECT countrycode,COUNT(district) FROM city GROUP BY countrycode;
SELECT countrycode,COUNT(ID) FROM city GROUP BY countrycode;
4、having
常用命令顺序为 select from where “group by” having
先执行group by之前的语句结果,having以该结果来执行后面的命令
统计中国每个省的总人口数,只打印总人口数小于100w
SELECT district,SUM(Population)
FROM city
WHERE countrycode='chn'
GROUP BY district
HAVING SUM(Population) < 1000000 ;
#HAVING之前的语句统计每个省的总人口数,HAVING后的语句筛选中国小于100w人口数量的省份
5、order by + limit
排序和限制
order by 从小到大的排序
order by desc 从大到小的排序
limit 限制显示查询的数量
LIMIT N ,M --->跳过N,显示一共M行
LIMIT 5,5 显示6到10行
LIMIT 3 显示前3行 === LIMIT 0,3
查看中国所有的城市,并按人口数进行排序(从大到小)
SELECT district,Population FROM city WHERE countrycode="CHN" ORDER BY Population DESC;
统计中国各个省的总人口数量,按照总人口从大到小排序
SELECT district,SUM(population)
FROM city
WHERE countrycode="CHN"
GROUP BY district
ORDER BY SUM(population) DESC;
统计中国,每个省的总人口,找出总人口大于500w的,并按总人口从大到小排序,只显示前三名
SELECT district,SUM(population)
FROM city
WHERE countrycode="CHN"
GROUP BY district
ORDER BY SUM(population) DESC
limit 3;
6、distinct:去重复
SELECT countrycode FROM city ;
SELECT DISTINCT(countrycode) FROM city ;
四、联合查询–union all
中国或美国城市信息
SELECT * FROM city WHERE countrycode in ("CHN","USA");
SELECT * FROM city WHERE countrycode='CHN'
UNION ALL
SELECT * FROM city WHERE countrycode='USA'
说明:一般情况下,我们会将 IN 或者 OR 语句 改写成 UNION ALL,来提高性能
UNION 去重复
UNION ALL 不去重复
五、别名
列别名,表别名
SELECT
a.Name AS an , #定义列别名
b.name AS bn , #定义列别名
b.SurfaceArea AS bs, #定义列别名
a.Population AS bp #定义列别名
FROM city AS a JOIN country AS b #定义表别名
ON a.CountryCode=b.Code #定义表别名
WHERE a.name ='shenyang';
#注意:列别名只能在结果中显示(以别名来替代原列的内容),不能在命令中调用;表别名可以在命令中调用,用于简化表名太长。
六、join 多表连接查询
按需求创建一下表结构,实验环境:
use school
stu :学生表
sno: 学号
sname:学生姓名
sage: 学生年龄
ssex: 学生性别
teacher :教师表
tno: 教师编号
tname:教师名字
course :课程表
cno: 课程编号
cname:课程名字
tno: 教师编号
score :成绩表
sno: 学号
cno: 课程编号
score:成绩
-- 项目构建
drop database school;
CREATE DATABASE school CHARSET utf8;
USE school
CREATE TABLE stu(
sno INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '学号',
sname VARCHAR(20) NOT NULL COMMENT '姓名',
sage TINYINT UNSIGNED NOT NULL COMMENT '年龄',
ssex ENUM('f','m') NOT NULL DEFAULT 'm' COMMENT '性别'
)ENGINE=INNODB CHARSET=utf8;
CREATE TABLE course(
cno INT NOT NULL PRIMARY KEY COMMENT '课程编号',
cname VARCHAR(20) NOT NULL COMMENT '课程名字',
tno INT NOT NULL COMMENT '教师编号'
)ENGINE=INNODB CHARSET utf8;
CREATE TABLE sc (
sno INT NOT NULL COMMENT '学号',
cno INT NOT NULL COMMENT '课程编号',
score INT NOT NULL DEFAULT 0 COMMENT '成绩'
)ENGINE=INNODB CHARSET=utf8;
CREATE TABLE teacher(
tno INT NOT NULL PRIMARY KEY COMMENT '教师编号',
tname VARCHAR(20) NOT NULL COMMENT '教师名字'
)ENGINE=INNODB CHARSET utf8;
INSERT INTO student(sno,sname,sage,ssex)
VALUES (1,'zhang3',18,'m');
INSERT INTO stu(sno,sname,sage,ssex)
VALUES
(2,'zhang4',18,'m'),
(3,'li4',18,'m'),
(4,'wang5',19,'f');
INSERT INTO stu
VALUES
(5,'zh4',18,'m'),
(6,'zhao4',18,'m'),
(7,'ma6',19,'f');
INSERT INTO stu(sname,sage,ssex)
VALUES
('oldboy',20,'m'),
('oldgirl',20,'f'),
('oldp',25,'m');
INSERT INTO teacher(tno,tname) VALUES
(101,'oldboy'),
(102,'hesw'),
(103,'oldguo');
DESC course;
INSERT INTO course(cno,cname,tno)
VALUES
(1001,'linux',101),
(1002,'python',102),
(1003,'mysql',103);
DESC sc;
INSERT INTO sc(sno,cno,score)
VALUES
(1,1001,80),
(1,1002,59),
(2,1002,90),
(2,1003,100),
(3,1001,99),
(3,1003,40),
(4,1001,79),
(4,1002,61),
(4,1003,99),
(5,1003,40),
(6,1001,89),
(6,1003,77),
(7,1001,67),
(7,1003,82),
(8,1001,70),
(9,1003,80),
(10,1003,96);
SELECT * FROM stu;
SELECT * FROM teacher;
SELECT * FROM course;
SELECT * FROM sc;
SELECT * FROM stu;
[school]>select * from stu;
+-----+---------+------+------+
| sno | sname | sage | ssex |
+-----+---------+------+------+
| 1 | zhang3 | 18 | m |
| 2 | zhang4 | 18 | m |
| 3 | li4 | 18 | m |
| 4 | wang5 | 19 | f |
| 5 | zh4 | 18 | m |
| 6 | zhao4 | 18 | m |
| 7 | ma6 | 19 | f |
| 8 | oldboy | 20 | m |
| 9 | oldgirl | 20 | f |
| 10 | oldp | 25 | m |
+-----+---------+------+------+
10 rows in set (0.00 sec)
SELECT * FROM teacher;
[school]>[school]>select * from teacher;
+-----+--------+
| tno | tname |
+-----+--------+
| 101 | oldboy |
| 102 | hesw |
| 103 | oldguo |
+-----+--------+
3 rows in set (0.00 sec)
SELECT * FROM course;
[school]>select * from course;
+------+--------+-----+
| cno | cname | tno |
+------+--------+-----+
| 1001 | linux | 101 |
| 1002 | python | 102 |
| 1003 | mysql | 103 |
+------+--------+-----+
3 rows in set (0.00 sec)
SELECT * FROM sc;
[school]>select * from sc;
+-----+------+-------+
| sno | cno | score |
+-----+------+-------+
| 1 | 1001 | 80 |
| 1 | 1002 | 59 |
| 2 | 1002 | 90 |
| 2 | 1003 | 100 |
| 3 | 1001 | 99 |
| 3 | 1003 | 40 |
| 4 | 1001 | 79 |
| 4 | 1002 | 61 |
| 4 | 1003 | 99 |
| 5 | 1003 | 40 |
| 6 | 1001 | 89 |
| 6 | 1003 | 77 |
| 7 | 1001 | 67 |
| 7 | 1003 | 82 |
| 8 | 1001 | 70 |
| 9 | 1003 | 80 |
| 10 | 1003 | 96 |
+-----+------+-------+
17 rows in set (0.01 sec)
多表查询语法
查询张三的家庭住址
SELECT A.name,B.address FROM
A JOIN B
ON A.id=B.id
WHERE A.name='zhangsan'
查询一下世界上人口数量小于100人的城市名和国家名
SELECT b.name ,a.name ,a.population
FROM city AS a
JOIN country AS b
ON b.code=a.countrycode
WHERE a.Population<100
查询城市shenyang,城市人口,所在国家名(name)及国土面积(SurfaceArea)
SELECT a.name,a.population,b.name ,b.SurfaceArea
FROM city AS a JOIN country AS b
ON a.countrycode=b.code
WHERE a.name='shenyang';
统计zhang3,学习了几门课
SELECT st.sname , COUNT(sc.cno)
FROM student AS st
JOIN
sc
ON st.sno=sc.sno
WHERE st.sname='zhang3'
查询zhang3,学习的课程名称有哪些?
SELECT st.sname , GROUP_CONCAT(co.cname)
FROM student AS st
JOIN sc
ON st.sno=sc.sno
JOIN course AS co
ON sc.cno=co.cno
WHERE st.sname='zhang3'
查询oldguo老师教的学生名.
SELECT te.tname ,GROUP_CONCAT(st.sname)
FROM student AS st
JOIN sc
ON st.sno=sc.sno
JOIN course AS co
ON sc.cno=co.cno
JOIN teacher AS te
ON co.tno=te.tno
WHERE te.tname='oldguo';
查询oldguo所教课程的平均分数
SELECT te.tname,AVG(sc.score)
FROM teacher AS te
JOIN course AS co
ON te.tno=co.tno
JOIN sc
ON co.cno=sc.cno
WHERE te.tname='oldguo'
每位老师所教课程的平均分,并按平均分排序
SELECT te.tname,AVG(sc.score)
FROM teacher AS te
JOIN course AS co
ON te.tno=co.tno
JOIN sc
ON co.cno=sc.cno
GROUP BY te.tname
ORDER BY AVG(sc.score) DESC ;
查询oldguo所教的不及格的学生姓名
SELECT te.tname,st.sname,sc.score
FROM teacher AS te
JOIN course AS co
ON te.tno=co.tno
JOIN sc
ON co.cno=sc.cno
JOIN student AS st
ON sc.sno=st.sno
WHERE te.tname='oldguo' AND sc.score<60;
查询所有老师所教学生不及格的信息
SELECT te.tname,st.sname,sc.score
FROM teacher AS te
JOIN course AS co
ON te.tno=co.tno
JOIN sc
ON co.cno=sc.cno
JOIN student AS st
ON sc.sno=st.sno
WHERE sc.score<60;
综合练习
查询平均成绩大于60分的同学的学号和平均成绩;
SELECT stu.sno,AVG(sc.score)
FROM stu
JOIN sc
ON stu.sno=sc.sno
HAVING AVG(sc.score)>60;
查询所有同学的学号、姓名、选课数、总成绩;
SELECT stu.sno,stu.sname,COUNT(sc.cno),SUM(sc.score)
FROM stu
JOIN sc
ON stu.sno=sc.sno
GROUP BY stu.sno;
查询各科成绩最高和最低的分:以如下形式显示:课程ID,最高分,最低分
SELECT sc.cno AS "课程ID",MAX(sc.score) AS "最高分", MIN(sc.score) AS "最低分"
FROM sc
JOIN course
ON sc.cno=course.cno
GROUP BY sc.cno;
统计各位老师,所教课程的及格率
select teacher.tname,course.cname,
count(case when sc.score>60 then 1 end)/count(sc.score)
from teacher
join course on teacher.tno=course.tno
join sc on course.cno=sc.cno
group by teacher.tno,course.cno;
查询每门课程被选修的学生数
SELECT course.cname, COUNT(stu.sno)
FROM course
JOIN sc
ON course.cno=sc.cno
JOIN stu
ON sc.sno=stu.sno
GROUP BY course.cname;
查询出只选修了一门课程的全部学生的学号和姓名
SELECT stu.sno,stu.sname,COUNT(sc.cno)
FROM stu
JOIN sc
ON stu.sno=sc.sno
GROUP BY stu.sno
HAVING COUNT(sc.cno)=1;
查询选修课程门数超过1门的学生信息
SELECT stu.sno,stu.sname,stu.sage,stu.ssex,COUNT(sc.cno)
FROM stu
JOIN sc
ON stu.sno=sc.sno
GROUP BY stu.sno
HAVING COUNT(sc.cno)>1;
统计每门课程:优秀(85分以上),良好(70-85),一般(60-70),不及格(小于60)的学生列表
SELECT course.cname,
GROUP_CONCAT(CASE WHEN sc.score>85 THEN stu.sname END ) AS 优秀,
GROUP_CONCAT(CASE WHEN sc.score>70 AND sc.score<=85 THEN stu.sname END) AS 良好,
GROUP_CONCAT(CASE WHEN sc.score>=60 AND sc.score<=70 THEN stu.sname END) AS 一般,
GROUP_CONCAT(CASE WHEN sc.score<60 THEN stu.sname END) AS 不及格
FROM course
JOIN sc ON course.cno=sc.cno
JOIN stu ON sc.sno=stu.sno
GROUP BY course.cname;
查询平均成绩大于85的所有学生的学号、姓名和平均成绩
SELECT stu.sno,stu.sname,AVG(sc.score)
FROM stu
JOIN sc
ON stu.sno=sc.sno
GROUP BY stu.sno
HAVING AVG(sc.score)>85;
stu.sno,stu.sname,stu.sage,stu.ssex,COUNT(sc.cno)
FROM stu
JOIN sc
ON stu.sno=sc.sno
GROUP BY stu.sno
HAVING COUNT(sc.cno)>1;
统计每门课程:优秀(85分以上),良好(70-85),一般(60-70),不及格(小于60)的学生列表
SELECT course.cname,
GROUP_CONCAT(CASE WHEN sc.score>85 THEN stu.sname END ) AS 优秀,
GROUP_CONCAT(CASE WHEN sc.score>70 AND sc.score<=85 THEN stu.sname END) AS 良好,
GROUP_CONCAT(CASE WHEN sc.score>=60 AND sc.score<=70 THEN stu.sname END) AS 一般,
GROUP_CONCAT(CASE WHEN sc.score<60 THEN stu.sname END) AS 不及格
FROM course
JOIN sc ON course.cno=sc.cno
JOIN stu ON sc.sno=stu.sno
GROUP BY course.cname;
查询平均成绩大于85的所有学生的学号、姓名和平均成绩
SELECT stu.sno,stu.sname,AVG(sc.score)
FROM stu
JOIN sc
ON stu.sno=sc.sno
GROUP BY stu.sno
HAVING AVG(sc.score)>85;