DQL语句也就是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 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 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 表 (不建议在生产环境使用)
use school; select * from stu;
2)查询stu表中,学生姓名和入学时间
use school; select sname,intime from stu
语句格式
SELECT col1,col2 FROM TABLE WHERE colN 条件;
查询中国(CHN)所有城市信息
SELECT * FROM city WHERE countrycode='CHN';
SELECT * FROM city WHERE NAME='peking';
查询甘肃省所有城市信息
SELECT * FROM city WHERE district='gansu';
<>表示为不等于!=
查询世界上少于100人的城市
SELECT * FROM city WHERE population<100;
2.3where配合逻辑运算符(and or )
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');
查询省的名字前面带guang开头的
SELECT * FROM city WHERE district LIKE 'guang%'; 注意:%不能放在前面,因为不走索引.
中国或美国城市信息
SELECT * FROM city WHERE countrycode IN ('CHN' ,'USA');
查询世界上人口数量大于100w小于200w的城市信息
SELECT * FROM city WHERE population >1000000 AND population <2000000; SELECT * FROM city WHERE population BETWEEN 1000000 AND 2000000;
group by:根据 by后面的条件进行分组,方便统计,by后面跟一个列或多个列
常用聚合函数
max() :最大值 min() :最小值 avg() :平均值 sum() :总和 count() :个数 group_concat() : 列转行
例子1:统计世界上每个国家的总人口数.
USE world;
SELECT countrycode,SUM(population) FROM city GROUP BY countrycode;
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;
常用命令顺序为 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人口数量的省份
排序和限制
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;
SELECT countrycode FROM city ;
SELECT DISTINCT(countrycode) FROM city ;
中国或美国城市信息 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)
[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'
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'
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 ;
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;
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;