zoukankan      html  css  js  c++  java
  • 十、Mysql的DQL语句

    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常用函数

    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;

    I have a dream so I study hard!!!
  • 相关阅读:
    leetcode 之 Palindrome Partitioning
    虚拟机共享文件夹下tar
    leetcode 之 Excel Sheet Column Number
    AndroidHttpClient & jsoup 解析 正方教务系统
    查看android下的分区表
    ubuntukylin 下编译 android4.4
    android:layout_weight 和 android: weightSum的使用
    Intent 与Bundle的传值关系
    使用自定义的Toast
    SlideMenu例子解析2
  • 原文地址:https://www.cnblogs.com/yaokaka/p/13951005.html
Copyright © 2011-2022 走看看