美文网首页
Day04-SQL基础应用+select练习

Day04-SQL基础应用+select练习

作者: 驮着集装箱的鲸鱼 | 来源:发表于2019-06-20 05:46 被阅读0次

    DQL使用

    1. select

    1.1 作用

    对表中的数据行进行查询
    

    1.2 单独使用select

    1.2.1 select @@xxxx;获取简单参数信息

    -- 查询my.cnf里面定义的端口

    3306 [(none)]>select @@port;
    +--------+
    | @@port |
    +--------+
    |   3306 |
    +--------+
    1 row in set (0.00 sec)
    
    3306 [(none)]>show variables like '%innodb%'; #详细参数列表
    
    1.2.2 select 函数( );

    -- 查看当前时间

    3306 [(none)]>select now();
    +---------------------+
    | now()               |
    +---------------------+
    | 2019-06-18 09:27:04 |
    +---------------------+
    1 row in set (0.00 sec)
    

    -- 查看当前所在库

    3306 [(none)]>use mysql;
    Reading table information for completion of table and column names
    You can turn off this feature to get a quicker startup with -A
    
    Database changed
    3306 [mysql]>select database();
    +------------+
    | database() |
    +------------+
    | mysql      |
    +------------+
    1 row in set (0.00 sec)
    

    -- 查看数据库版本

    3306 [mysql]>select version();
    +------------+
    | version()  |
    +------------+
    | 5.7.26-log |
    +------------+
    1 row in set (0.09 sec)
    

    1.3 SQL 92标准的使用语法

    1.3.1 select 语法执行顺序(单表)
    select开始 ---》
    from子句---》
    where子句---》
    group by子句---》
    select后执行条件---》
    having子句---》
    order by子句---》
    limit
    
    1.3.2 from(select后面必须跟from)

    -- 例1:查询city表中的所有数据

    use world;
    select * from city; #查所有数据,这种方法仅适合数据行较少的表(小表),生产中使用较少,可能会造成数据库查询缓慢。
    select * from world.city;
    

    -- 例2:查询name和population的所有值。(查看2列的值)

    select name , population from city;
    select name , population form world.city;  #推荐使用这种方法
    
    1.3.3 单表查询练习环境:world数据库下的表介绍

    查看库中所有表

    show tables from world;
    city:(城市)
    desc city;
    id:自增的无关列,数据行的需要
    name:城市名字
    countrycode:城市所在的代号,CHN(中国)、USA(美国)、JPN(日本)……
    district:中国是省的意思,美国是洲的意思
    population:城市人口数量
    说明:该数据为历史数据,仅供学习交流使用。
    

    刚入职时,如何熟悉业务:

    刚入职时DBA的任务,就是熟悉业务。
    1. 先搞清楚架构,通过公司的架构图,搞清楚数据库的物理架构。(多少台机器,使用什么样的软件),一般时间为1-2天。
    2. 逻辑结构(2-3周内)
    (1)生产库的信息(库的个数、库名)
    (2)库下面表的信息(非常复杂)
    1. 与业务人员和开发搞好关系,从他们口中得知详细信息。
    2. 搞到ER图(实景关系图,PD)
    3. 啥都没有怎么办?
    (1)找到建表语句,如果有注释,读懂注释就可以了。如果没有注释,只能根据列名翻译。
    (2)找到表中部分数据,分析数据特点,达到了解数据功能的目的。
    
    1.3.3 where(相当于Linux中的grep)

    -- 例子1(生产常用):
    -- where配合等值(=)查询
    -- 查询中国的城市信息

    select * from world.city where countrycode='CHN';
    

    -- 查询美国的城市信息

    select * from world.city where countrycode='USA';
    

    -- where配置不等值(>、<、>=、<=、<>)
    -- 查询世界人口数量小于100人的城市

    select * from world.city where population<100;
    

    -- 查询世界人口数量大于10000000人口的城市

    select * from world.city where population>10000000;
    

    -- where 配合模糊查询(like)

    -- 查询国家代号是C开头的城市

    select * from world.city where countrycode like 'C%';
    --- 注意:like语句在MySQL中,不要出现%在前的情况。因为效率很低,不走索引。
    

    -- where 配合 逻辑连接符(and和or)
    -- 查询城市人口在10000到20000之间的城市(and)

    select * from city where population > 10000 and population < 20000;
    select * from city where population between 10000 and 20000;
    

    -- 查询中国或美国的城市信息(or)

    select * from city where countrycode='CHN' or countrycode='USA';
    select * from city where countrycode in ('CHN','USA'); 
    select * from city where countrycode='CHN'
    union all
    select * from city where countrycode='USA'; ##建议使用这种
    

    面试题:union与union all的区别:

    union [distinct]合并
    union all 不合并(性能更好,不用排序)
    
    1.3.4 group by(分组条件) 配合聚合函数应用

    常用聚合函数:

    avg():平均值
    count():计算
    sum():总数
    max():最大
    min():最小
    group_concat():列转行
    

    -- 统计全世界每个国家的总人口数

    select countrycode,sum(population) from city group by countrycode;
    

    解题思路
    -- 统计每个国家的城市个数

    1. 拿什么站队
    国家(countrycode)--->goup by countrycode
    2. 拿什么统计
    城市ID或城市名name
    3. 统计的是什么
    count(id)
    
    select countrycode,count(id) from city group by countrycode;
    

    -- 统计并显示每个国家省的名字列表

    select countrycode,group_concat(district) from city group by countrycode;
    

    -- 统计中国每个省的城市列表名

    select district,group_concat(name) from city where countrycode='CHN' group by district;
    

    -- 统计中国每个省的总人口数

    select district,sum(population) from city where countrycode='CHN' group by district;
    
    1.3.5 having(二级过滤)

    --- 统计中国每个省的总人口数大于1千万的省人口数

    select district,sum(population) from city where countrycode='CHN' group by district having sum(population)>10000000;
    结论:having后的条件是不走索引的,可以进行一些优化手段。
    
    1.3.6 order by

    -- 中国每个省的总人口数总人口数从大到小显示

    select District,sum(population) from city where CountryCode='CHN' group by District order by sum(population) desc;
    

    -- 中国每个省的总人口数从小到大显示

    select District,sum(population) from city where CountryCode='CHN' group by District order by sum(population);
    

    --- 例子:查询中国所有的城市,并以人口数降序输出

    SELECT * FROM city WHERE countrycode='CHN' ORDER BY  population DESC;
    
    1.3.7 limit

    -- 显示中国城市人口数排在前5的城市

    SELECT * FROM city WHERE countrycode='CHN' ORDER BY  population DESC limit 5; 显示前5名
    

    -- 显示中国城市人口数排在6-10名的城市

    SELECT * FROM city WHERE countrycode='CHN' ORDER BY  population DESC limit 5,5;#跳过前5行。显示后5行
    
    SELECT * FROM city WHERE countrycode='CHN' ORDER BY  population DESC limit 5 offset 5;
    limit m,n 跳过m行,显示n行
    limit x offset y 跳过y行,显示x行
    

    1.4 多表连接查询

    1.4.1 介绍测试表的关系

    1.4.2 为什么要使用多表连接查询?

    需要查询的数据时来自于多张表时
    

    1.4.3 怎么去多表连接查询

    (1)传统的连接:基于where条件(了解)
    (2)自连接(了解、自行扩展)
    (3)内连接#常用(超重点)
    1. 找表之间的关系列
    2. 排列查询条件
    3. 将关联条件列放在on 后面(on A.X=B.X)
    4. 将所有的查询条件进行罗列
    select A jioin B on A.X=B.y where group by oreder by limit;
    

    -- 例子:
    -- 1. 查询世界上人口数量小于100人的国家名、城市名、国土面积

    select country.name,city.name,country.surfacerea
    from city join country
    on city.countrycode=country.code
    where city.population<100;
    

    -- 查询oldguo老师和他教的课程名称。

    SELECT teacher.tname ,course.cname
    FROM teacher 
    JOIN course 
    ON teacher.tno=course.tno
    WHERE teacher.tname='oldguo';
    

    -- 统计每门课程的总成绩

    select course.cname,sum(sc.score)
    from course
    join sc
    on course.cno = sc.cno
    group by course.cno,course.cname;
    

    -- 5.7 版本会报错的情况,在sqlyog中以下操作没问题, 但是在命令行上是会报错

    SELECT course.cno,course.cname,SUM(sc.score)
    FROM course  
    JOIN sc 
    ON course.cno = sc.cno
    GROUP BY course.cname;
    
    ERROR 1055 (42000): Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column 'school.course.cno' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
    (原因是:开了sql_mode=only_full_group_by导致的
    1. 在select 后面出现的列cno,即不是分组条件(group by),也没有在函数内包裹(没有在函数括号内)出现。),所以报错了。
    2. 如果group by后是主键列,或者是唯一列,就能行。如下:
    SELECT course.cno,course.cname,SUM(sc.score)
    FROM course  
    JOIN sc 
    ON course.cno = sc.cno
    GROUP BY course.cno;
    

    -- 例子:
    --- 4. 查询oldguo老师教的学生姓名列表

    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
    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(concat(student.sname,":",sc.score))
    from teacher
    join course
    on teacher.tno=course.tno
    join sc
    on course.cno=sc.cno
    join student
    on sc.sno=student.sno
    where teacher.tname='oldguo' and sc.score<60
    group by teacher.tno;
    

    -- 7. 统计zhang3,学习了几门课

    SELECT student.`sname` ,COUNT(sc.`cno`)
    FROM student
    JOIN sc
    ON student.`sno`=sc.`sno`
    WHERE student.sname='zhang3';
    

    -- 8. 查询zhang3,学习的课程名称有哪些?

    select student.sname,group_concat(course.cname)
    from student
    join sc
    on student.sno=sc.sno
    join course
    on sc.cno=course.cno
    where student.sname='zhang3'
    group by course.cno;
    

    -- 9. 查询oldguo老师教的学生名.

    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
    where teacher.tname='oldguo'
    group by teacher.tno;
    

    -- 10.查询oldguo所教课程的平均分数

    select teacher.tname,avg(sc.score)
    from teacher
    join course
    on teacher.tno=course.tno
    join sc
    on course.cno=sc.cno
    where teacher.tname='oldguo';
    

    -- 11.每位老师所教课程的平均分,并按平均分排序

    select teacher.tname,avg(sc.score)
    from teacher
    join course
    on teacher.tno=course.tno
    join sc
    on course.cno=sc.cno
    group by teacher.tno
    order by avg(sc.score) desc;
    

    -- 12.查询oldguo所教的不及格的学生姓名

    select teacher.tname,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
    where teacher.tname='oldguo' and sc.score < 60
    group by student.sno;
    

    -- 13.查询所有老师所教学生不及格的信息

    SELECT teacher.tname,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
    WHERE sc.score<60;
    

    相关文章

      网友评论

          本文标题:Day04-SQL基础应用+select练习

          本文链接:https://www.haomeiwen.com/subject/soqxqctx.html