ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

数据库查询语句DQL

2021-01-17 20:02:21  阅读:140  来源: 互联网

标签:语句 -- 数据库 查询 score student DQL id SELECT


表与表之间的关系

  • 概念:表与表之间的关系,在理解上,一张表中的数据对应另外一张表中的数据关系,从每一行理解。

一对一关系

image-20201223094835942

一对多关系

image-20201223095356024

多对多关系

image-20201223100621580

一、数据库查询语句DQL

/*
Navicat MySQL Data Transfer
Source Server         : localhost
Source Server Version : 80022
Source Host           : 127.0.0.1:3306
Source Database       : db_school
Target Server Type    : MYSQL
Target Server Version : 80022
File Encoding         : 65001
Date: 2020-12-23 14:47:16
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
  `c_id` varchar(20) NOT NULL,
  `c_name` varchar(20) NOT NULL DEFAULT '',
  `t_id` varchar(20) NOT NULL,
  PRIMARY KEY (`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('01', '语文', '02');
INSERT INTO `course` VALUES ('02', '数学', '01');
INSERT INTO `course` VALUES ('03', '英语', '03');
-- ----------------------------
-- Table structure for score
-- ----------------------------
DROP TABLE IF EXISTS `score`;
CREATE TABLE `score` (
  `s_id` varchar(20) NOT NULL,
  `c_id` varchar(20) NOT NULL,
  `s_score` int DEFAULT NULL,
  PRIMARY KEY (`s_id`,`c_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of score
-- ----------------------------
INSERT INTO `score` VALUES ('01', '01', '80');
INSERT INTO `score` VALUES ('01', '02', '90');
INSERT INTO `score` VALUES ('01', '03', '99');
INSERT INTO `score` VALUES ('02', '01', '70');
INSERT INTO `score` VALUES ('02', '02', '60');
INSERT INTO `score` VALUES ('02', '03', '80');
INSERT INTO `score` VALUES ('03', '01', '80');
INSERT INTO `score` VALUES ('03', '02', '80');
INSERT INTO `score` VALUES ('03', '03', '80');
INSERT INTO `score` VALUES ('04', '01', '50');
INSERT INTO `score` VALUES ('04', '02', '30');
INSERT INTO `score` VALUES ('04', '03', '20');
INSERT INTO `score` VALUES ('05', '01', '76');
INSERT INTO `score` VALUES ('05', '02', '87');
INSERT INTO `score` VALUES ('06', '01', '31');
INSERT INTO `score` VALUES ('06', '03', '34');
INSERT INTO `score` VALUES ('07', '02', '89');
INSERT INTO `score` VALUES ('07', '03', '98');
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
  `s_id` varchar(20) NOT NULL,
  `s_name` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '',
  `s_birth` varchar(20) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '',
  `s_sex` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '',
  `age` int DEFAULT NULL,
  `height` int DEFAULT NULL,
  PRIMARY KEY (`s_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES ('01', '赵雷', '1990-01-01', '男', '23', '160');
INSERT INTO `student` VALUES ('02', '钱电', '1990-12-21', '女', '26', '165');
INSERT INTO `student` VALUES ('03', '孙风', '1990-05-20', '男', '20', '155');
INSERT INTO `student` VALUES ('04', '李云', '1990-08-06', '保密', '19', '180');
INSERT INTO `student` VALUES ('05', '周梅', '1991-12-01', '女', '22', '175');
INSERT INTO `student` VALUES ('06', '吴兰', '1992-03-01', '女', '18', '167');
INSERT INTO `student` VALUES ('07', '郑竹', '1989-07-01', '男', '24', '158');
INSERT INTO `student` VALUES ('08', '王菊', '1990-01-20', '女', '25', '176');
INSERT INTO `student` VALUES ('09', '李云龙', '1990-01-20', '男', '26', '163');
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
  `t_id` varchar(20) NOT NULL,
  `t_name` varchar(20) NOT NULL DEFAULT '',
  PRIMARY KEY (`t_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of teacher
-- ----------------------------
INSERT INTO `teacher` VALUES ('01', '张三');
INSERT INTO `teacher` VALUES ('02', '李四');
INSERT INTO `teacher` VALUES ('03', '王五');

1.1简单查询语句

  • 简单查询

    -- 1、使用查询语句,将一张表中所有的数据查询出来
    SELECT * FROM student;(不推荐使用,在开发里面,禁止使用)
    -- 推荐在查询的时候,用字段名称替换*,字段名可以只写部分
    SELECT s_id,s_name,s_birth,s_sex,age FROM student;
    
  • 条件查询:需要使用到关键字WHERE

    -- 1、根据id值查询指定的学生数据,结果集只有一条
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE s_id = 1;
    -- 2、查询性别为男的所有学生数据,结果集有多条
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE s_sex = "男";
    -- 3、多条件查询,多个条件一起查询,会使用到逻辑运算符,比如:查询小于20岁的所有男学生
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE s_sex = "男" AND age < 20;
    -- 4、多条件查询,多个条件一起查询,比如:查询所有的男学生,或者年龄小于20的
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE    s_sex = "男" OR age < 20;
    -- 5、如果使用or条件,一定要注意sql注入
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE s_sex = "男" OR 1 = 1;
    -- 6、查询出性别不等于男,会将女学生或者保密的学生
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE s_sex <> "男";
    -- 7、使用条件选定范围内的数据,不如查询出年龄在18到22岁之间的学生
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE age > 18 AND age < 22;
    -- 8、选择一定范围内的数据可以使用关键字between,两端数据都包含
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE age between 18 AND 22;
    
  • 模糊查询,需要使用到关键字like,在实际开发中,为了提高数据库的查询效率,要尽量避免使用模糊查询,

    -- 如果要使用模糊查询,需要使用到占位符:_和%
    -- _表示单个占位符
    -- % 多个占位符
    -- 使用模糊查询,将姓李的所有学生查询出来
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE s_name LIKE "李_";
    -- 使用模糊查询,查询出名字中有李的名称
    SELECT s_id,s_name,s_birth,s_sex,age FROM student WHERE s_name LIKE "李%";
    
  • 排序查询:有一些字段,可以通过对其进行排序查询结果,排序分为升序和降序,要用到关键字ORDER BY

    -- 排序语法:SELECT 字段 FROM 表 ORDER BY 要排序的字段 排序规则(ASC升序,DESC降序,默认升序)
    -- 按照学生的年龄进行升序排列
    SELECT s_id,s_name,s_birth,s_sex,age FROM student ORDER BY age ASC;
    -- 按照学生的身高,降序排列
    SELECT s_id,s_name,s_birth,s_sex,age,height FROM student ORDER BY height DESC;
    
  • 分组查询,在一个表中,按照特定的字段进行分组,要使用到关键字GROUP BY

    -- 5.7以后处理group by问题,在my.ini文件中,添加上配置参数:
    [msyqld]
    sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION'
    -- 查询成绩表,根据学号分组
    SELECT s_id,c_id,s_score FROM score GROUP BY s_id;
    -- 在分组查询中,要使用聚合函数,分组才有意义,聚合函数都是放在SELECT关键字后面
    -- 1、查询出一个分组中某一个字段的和:SUM(字段名)
    -- 2、查询出一个分组中某一个字段的平均数:AVG(字段名)
    -- 3、统计出某一个分组的数据个数:COUNT(字段名)
    -- 4、查询出一个分组中某一个字段的最大值:MAX(字段名)
    -- 5、查询出一个分组中某个字段的最小值:MIN(字段名)
    -- 查询出每个学生的总成绩
    SELECT s_id,SUM(s_score) FROM score GROUP BY s_id;
    -- 查询出每个学生的平均成绩
    SELECT s_id AS 学号,AVG(s_score) FROM score GROUP BY s_id;
    -- 统计出每个学生学了多少门课程
    SELECT s_id AS 学号,COUNT(c_id) AS 课程数 FROM score GROUP BY s_id;
    -- 通过sum函数和count函数计算平均成绩
    SELECT s_id AS 学号,SUM(s_score) / COUNT(c_id) AS 平均成绩 FROM score GROUP BY s_id;
    -- 找出该学生的最高成绩
    SELECT s_id AS 学号,MAX(s_score) FROM score GROUP BY s_id;
    -- 找出该学生的最低成绩
    SELECT s_id AS 学号,MIN(s_score) FROM score GROUP BY s_id;
    -- 找出平均成绩高于60分的学生,如果是把聚合函数的结果作为条件再次筛选,则需要用关键字HAVING,并且放在GROUP BY后面
    SELECT s_id AS 学号,AVG(s_score) AS 平均成绩 FROM score GROUP BY s_id HAVING AVG(s_score) > 60;
    -- 将聚合函数的结果作为排序的条件
    SELECT s_id AS 学号,SUM(s_score) AS 总成绩 FROM score  GROUP BY s_id ORDER BY SUM(s_score) DESC;
    
  • 筛选个数,需要使用关键字LIMIT,在分页的时候会使用到

    -- 从查询的结果集中,只要其中的几条数据,
    -- 语法:LIMIT 起始位置(从0开始计数),查询的条数;
    SELECT s_id,s_name,s_birth,s_sex,age,height FROM student LIMIT 0,5;
    
  • 去重:会使用关键字DISTINCT,作用是将查询结果集中的某些字段的重复数据只保留一个

    --  查询成绩表,根据学号进行去重。比如:查询出那些学生是有成绩的
    SELECT DISTINCT s_id FROM score;
    

1.2 查询语句的执行顺序

  • 一条完整的查询语句

    SELECT DISTINCT 字段 FROM 表名 WHERE 字段条件 GROUP BY 字段 HAVING 聚合函数条件 ORDER BY 字段 排序规则 LIMIT 起始位置,显示条数;
    
  1. 执行FROM,将硬盘中的数据放到内存中
  2. 执行WHERE,将普通字段的条件进行筛选
  3. 查询语句中是否有GROUP BY,如果有按照规则分组,如果没有,则默认分为一个组
  4. 查询语句中,是否有HAVING,如果有将聚合函数作为条件,进行筛选
  5. 执行SELECT,将要查询的结果的字段挑选出来
  6. 执行DISTINCT将结果中重复的数据只显示一个
  7. 执行ORDER BY,如果没有,则按照升序排列
  8. 筛选LIMIT

1.3 子查询

  • 可以实现多表查询,将一个表查询的结果,作为另外一张表的条件,进行查询

    -- 第一步:查询出总成绩最高的学生学号
    SELECT s_id AS 学号 FROM socre GROUP BY s_id ORDER BY SUM(S_SCORE) DESC LIMIT 0,1;
    -- 第二步:查询出01学号学生的所有信息
    SELECT s_id,s_name,s_birth,s_sex,age,height FROM student WHERE s_id = '01';
    -- 如果已知条件就是两张表,要求查询出总成绩最高的学生的信息
    SELECT s_id,s_name,s_birth,s_sex,age,height FROM student WHERE s_id = (SELECT s_id FROM score 
    GROUP BY s_id ORDER BY SUM(s_score) DESC LIMIT 0,1);
    -- 查询出有成绩的学生的信息
    SELECT s_id,s_name,s_birth,s_sex,age,height FROM student WHERE s_id in (SELECT DISTINCT s_id FROM score);
    -- 查询出没有成绩的学生信息
    SELECT s_id,s_name,s_birth,s_sex,age,height FROM student WHERE s_id not in (SELECT DISTINCT s_id FROM score);
    -- 查询出平均成绩高于60分的学生信息
    SELECT s_id,s_name,s_birth,s_sex,age,height FROM student WHERE s_id IN (SELECT s_id FROM score 
    GROUP BY s_id HAVING AVG(s_score) > 60);
    -- exists:子查询语句中有结果,则主查询语句执行,如果子查询语句中没有结果,则主查询语句不执行。
    -- 举例:
    SELECT s_id,s_name,s_sex,s_birth,age,height FROM student WHERE EXISTS(SELECT s_id FROM score WHERE 
    s_score = 100);
    

1.4 链接查询

  • 一些复杂的查询语句,在一张表中并不能查询出结果,多表一起查询,使用链接查询将有关系的表进行连接,链接成一张表,然后在用筛选、分组、排序等进行操作。

    -- 交叉链接:因为会产生笛卡尔积,因此禁止使用
    -- 举例:查询所有学生的信息及学生对应的成绩
    SELECT  s1.s_id,s_name,s_sex,s_birth,age,height,s2.s_id,c_id,s_score FROM student AS s1,score AS s2 WHERE s1.s_id = s2.s_id;
    -- 内连接:......FROM 表1 INNER JOIN 表2 ON 主外键链接条件
    -- 举例:查询所有学生的信息及学生对应的成绩
    SELECT s1.s_id,s_name,s_sex,s_birth,age,height,s2.s_id,c_id,s_score FROM student AS s1 INNER JOIN score AS s2 ON s1.s_id = s2.s_id;
    -- 内连接举例:查询出所有学生学习的课程信息及对应的成绩
    SELECT s1.s_id,s_name,s_sex,s_birth,age,height,s2.s_id,s2.c_id,s_score,c.c_id,c_name,t_id FROM student AS s1 JOIN score AS s2 ON s1.s_id = s2.s_id JOIN course AS c ON s2.c_id = c.c_id;
    -- 在上面的基础上, 可以继续进行筛选,查询出所有学生中成绩最高的学生信息、课程信息和成绩
    SELECT s1.s_id,s_name,s_sex,s_birth,age,height,s2.s_id,s2.c_id,s_score,c.c_id,c_name,t_id FROM student AS s1 JOIN score AS s2 ON s1.s_id = s2.s_id JOIN course AS c ON s2.c_id = c.c_id ORDER BY s_score DESC LIMIT 0,1;
    -- 查询出所有老师教的所有课程的所有成绩的所有学生信息
    SELECT s1.s_id,s_name,s_sex,s_birth,age,height,s2.s_id,s2.c_id,s_score,c.c_id,c_name,c.t_id,t.t_id,t_name FROM student AS s1 JOIN score AS s2 ON s1.s_id = s2.s_id JOIN course AS c ON s2.c_id = c.c_id JOIN teacher AS t ON c.t_id = t.t_id;
    -- 外连接:左外连接和右外连接
    -- 左外连接:以左边的表为基准,右边的表如果对应的没有数据,则用null来表示,左边的表一定要有数据,语法:FROM 表1 LEFT JOIN  表2 ON 条件。
    SELECT s1.s_id,s_name,s_sex,s_birth,age,height,s2.s_id,c_id,s_score FROM student AS s1 LEFT JOIN score AS s2 ON s1.s_id = s2.s_id;
    -- 右外连接
    -- 以右边的表为基准,左边的表如果对应的没有数据,则用null来表示,右边的表一定要有数据,语法:FROM 表1 RIGHT JOIN  表2 ON 条件。
    SELECT s1.s_id,s_name,s_sex,s_birth,age,height,s2.s_id,c_id,s_score FROM student AS s1 RIGHT JOIN score AS s2 ON s1.s_id = s2.s_id;
    

tudent AS s1 LEFT JOIN score AS s2 ON s1.s_id = s2.s_id;
– 右外连接
– 以右边的表为基准,左边的表如果对应的没有数据,则用null来表示,右边的表一定要有数据,语法:FROM 表1 RIGHT JOIN 表2 ON 条件。
SELECT s1.s_id,s_name,s_sex,s_birth,age,height,s2.s_id,c_id,s_score FROM student AS s1 RIGHT JOIN score AS s2 ON s1.s_id = s2.s_id;

标签:语句,--,数据库,查询,score,student,DQL,id,SELECT
来源: https://blog.csdn.net/M_J_R/article/details/112756653

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有