数据库DQL数据查询语言

news2024/9/25 23:21:37

文章目录

  • DQL数据查询语言
    • 语法:
    • 基础查询
      • 语法:
    • WHERE子句
      • 使用AND"与"和OR"或"来连接多个条件进行查询
      • IN(列表):等于列表其中之一(在列表中)
      • NOT IN(列表):不在列表中,不能等于列表中的所有项
      • BETWEEN...AND...:在一个范围之内
      • DISTINCT去重操作。在结果集中去除指定字段值相同的记录
      • LIKE 模糊查询
      • NULL值判断
    • ORDER BY子句
    • 分页查询
        • 语法:
    • DQL中可以使用函数或者表达式进行查询
      • 使用表达式
      • 使用函数
    • 在WHERE子句中使用函数或表达式作为过滤条件
      • 使用表达式
      • 使用函数
      • 别名
        • 语法
      • 聚合函数
      • GROUP BY子句,分组
        • 按照单字段分组
        • 按照多字段分组
        • 按照聚合函数排序
      • HAVING子句,在分组统计时添加过滤条件
      • 聚合函数不能被应用与WHERE子句
      • HAVING子句
      • 子查询
        • 子查询使用场景
        • 子查询分类
        • 在DQL语句中使用子查询
        • 在DML中使用子查询
        • 在DDL中使用子查询
      • 关联查询(重点知识)
        • 笛卡尔积
        • 关联查询语法:
          • 关联查询中可以指定过滤条件
        • N张表关联查询至少要有N-1个连接条件
        • HAVING和WHERE的区别

DQL数据查询语言

DQL是用于查询表中数据的语言。

语法:

SELECT 子句
FROM 子句
WHERE 子句
  JOIN...ON...子句
GROUP BY 子句
HAVING 子句
ORDER BY子句

一条DQL语句至少要包含的两个子句分别是SELECT子句和FROM子句

  • SELECT子句用于指定查询的字段名称。选定的字段会体现在查询结果集中
  • FROM子句用于指定数据来自那些表(指定查询的表)

基础查询

由SELECT和FROM构成。

语法:

  • SELECT子句和FROM子句

    SELECT 字段1[,字段2,字段3,...]
    FROM1[,2,3...]
    
  • SELECT子句中可以使用*表达查询所有的字段

    实际开发中不推荐使用,因为查询低效*

查询teacher表中的所有数据
SELECT * FROM teacher
上述SQL执行时,数据库会先解析"*",这个操作会导致数据库先查看内部数据字典了解表的字段后
才能查看表中数据。由于查询是非常频繁的操作,因此每次查看数据字段无疑是浪费性能且消耗时间的操作!
全字段查询时应当在SELECT子句中将所有字段全部列出来(后期java程序执行时)。
如果是手动临时查询,可以使用*。


查看每个老师的名字,职称,工资,性别
SELECT name,title,salary,gender
FROM teacher

WHERE子句

在DQL中用于筛选查询的记录。最终数据库仅将满足WHERE子句条件的记录体现在结果集中。

  • 查看职称为"一级讲师"的老师名字和工资?

    1:查询的是老师信息,能确定FROM子句中的表名为teacher
    2:查看的是老师的名字和工资,能确定SELECT子句中的字段name和salary
    3:由于仅查看"一级讲师",能确定WHERE子句过滤条件为title='一级讲师'
    SELECT name,salary,title
    FROM teacher
    WHERE title='一级讲师'
    
  • 查看除’刘苍松’老师以外的其他老师的名字,工资和年龄?

    SELECT name,salary,age
    FROM teacher
    WHERE name<>'刘苍松'
    
  • 查看所有职位是’大队长’的同学的名字年龄和性别

    SELECT name,age,gender
    FROM student
    WHERE job='大队长'
    
  • 查看年龄在30(含)岁以上的老师都有谁?查看老师的名字,年龄,性别,工资

    SELECT name,age,gender,salary
    FROM teacher
    WHERE age>=30
    

使用AND"与"和OR"或"来连接多个条件进行查询

  • AND:都为真时才为真
  • OR:都为假时才为假

  • 查看7岁的大队长都是谁?列出:名字,年龄,性别,职位

    SELECT name,age,gender,job
    FROM student
    WHERE job='大队长' AND age=7
    
  • 查看班级编号小于6的所有中队长的名字,年龄,性别,职位和所在班级编号

    SELECT name,age,gender,job,class_id
    FROM student
    WHERE class_id<6 AND job='中队长'
    
  • 查看所有一级讲师和三级讲师的名字,职称,工资?

    SELECT name,title,salary
    FROM teacher
    WHERE title='一级讲师' OR title='三级讲师'
    
  • 查看所有大队长,中队长和小队长的名字,年龄,性别

    SELECT name,age,gender
    FROM student
    WHERE job='大队长' OR job='中队长' OR job='小队长'
    
  • 查看班级编号在6(含)以下的所有大队长和中队长的名字,年龄,职位,班级编号

    AND的优先级是高于OR的

    可以使用()提高优先级

    SELECT name,age,job,class_id
    FROM student
    WHERE class_id<=6 AND job='大队长' OR job='中队长'
    上述SQL的条件应当读作:查看班级编号6以下的大队长和所有班级编号的中队长
    
    
    SELECT name,age,job,class_id
    FROM student
    WHERE class_id<=6 AND (job='大队长' OR job='中队长')
    提高OR的优先级满足查询要求
    

IN(列表):等于列表其中之一(在列表中)

  • 查看所有的大队长,中队长,小队长的名字,年龄,性别

    SELECT name,age,gender
    FROM student
    WHERE job='大队长' OR job='中队长' OR job='小队长'
    等价于
    SELECT name,age,gender
    FROM student
    WHERE job IN('大队长','中队长','小队长')
    
  • 查看所有一级讲师,二级讲师,三级讲师的老师名字,职称和工资?

    SELECT name,title,salary
    FROM teacher
    WHERE title IN ('一级讲师','二级讲师','三级讲师')
    

NOT IN(列表):不在列表中,不能等于列表中的所有项

  • 查看一级讲师和二级讲师以外的所有老师的名字,职称,工资?
 SELECT name,title,salary
 FROM teacher
 WHERE title NOT IN('一级讲师','二级讲师')
  • 查看不是中队长和大队长以及小队长的其他学生的名字,年龄,职位

    SELECT name,age,job
    FROM student
    WHERE job NOT IN('大队长','中队长','小队长')
    

BETWEEN…AND…:在一个范围之内

  • 查看工资在2000-5000之间的老师的名字,工资,职称?

    SELECT name,salary,title
    FROM teacher
    WHERE salary>=2000 AND salary<=5000
    等价于
    SELECT name,salary,title
    FROM teacher
    WHERE salary BETWEEN 2000 AND 5000
                         下限      上限
    
  • 查看年龄在7-10岁之间的学生的名字,年龄,性别

    SELECT name,age,gender
    FROM student
    WHERE age BETWEEN 7 AND 10
    
  • 查看年龄在20-35岁之间的男老师的名字,职称,年龄

    SELECT name,title,age
    FROM teacher
    WHERE age BETWEEN 20 AND 35
    AND gender='男'
    
  • 查看3-5楼的班级名称都是什么?

    SELECT name
    FROM class
    WHERE floor BETWEEN 3 AND 5
    

DISTINCT去重操作。在结果集中去除指定字段值相同的记录

语法

SELECT DISTINCT 字段1[,字段2,...]
FROM 表名
...
  • DISTINCT关键字必须紧跟在SELECT子句之后
  • DISTINCT后面可以指定多个字段,当这几个字段组合相同的记录会在结果集中被去除

  • 查看老师的职称都有哪些?

    SELECT title
    FROM teacher
    上述SQL语句的查询结果集是展现每个老师的职称,与查询需求不匹配
    
    SELECT DISTINCT title
    FROM teacher
    将查询结果集中重复的title去除后得到正确效果
    
  • 查看学生的职位都有哪些?

    SELECT DISTINCT job
    FROM student
    
  • 查看各年龄的职位都有哪些?

    SELECT DISTINCT age,job
    FROM student
    

练习:

1.查看负责课程编号(subject_id)1的男老师都有谁?
  SELECT name,salary,title
  FROM teacher
  WHERE subject_id=1 AND gender='男'
  
2.查看工资高于5000的女老师都有谁?
  SELECT name,salary,title
  FROM teacher
  WHERE salary>5000 AND gender='女'
  
3.查看工资高于5000的男老师或所有女老师的工资?
  SELECT name,salary,gender
  FROM teacher
  WHERE salary>5000 AND gender='男' OR gender='女'

4.查看所有9岁学生的学习委员和语文课代表都是谁?
  SELECT name,job,age
  FROM student
  WHERE age=9 AND (job ='学习委员' OR job='语文课代表')

5.查看工资在600010000之间的老师以及具体工资?
  SELECT name,salary,title
  FROM teacher
  WHERE salary BETWEEN 6000 AND 10000
  
6.查看工资在40008000以外的老师及具体工资?
  SELECT name,salary,title
  FROM teacher
  WHERE salary NOT BETWEEN 4000 AND 8000
  
7.查看老师负责的课程编号都有什么?
  SELECT DISTINCT subject_id
  FROM teacher

8.查看所有女老师的职称都是什么?
  SELECT DISTINCT title
  FROM teacher
  WHERE gender='女'
  
9.查看7-10岁的男同学的职位都有哪些?
  SELECT DISTINCT job
  FROM student
  WHERE age BETWEEN 7 AND 10
  AND gender='男'
  
10.查看一级讲师和二级讲师的奖金(comm)是多少?
   SELECT name,comm
   FROM teacher
   WHERE title IN ('一级讲师','二级讲师')
   
11.查看除老板和总监的其他老师的工资和奖金是多少?
   SELECT name,title,salary,comm
   FROM teacher
   WHERE title NOT IN('老板','总监')

12.查看'3年级2班''5年级3班'在那层楼?
   SELECT name,floor
   FROM class
   WHERE name IN('3年级2班','5年级3班')

LIKE 模糊查询

LIKE中有两个通配符:

  • _:下划线表示一个字符(1个)
  • %:百分号表示任意个字符(0-多个)

组合示意:

%X%:字符串中含有X。
X%:字符串是以X字符开始的。
%X:字符串是以X字符结尾的。
__X:三个字符,且最后一个字符是X的。
%X_:倒数第二个字符是X的。

  • 查看名字中含有’苍’的老师?

    SELECT name,title,salary
    FROM teacher
    WHERE name LIKE '%苍%'
    
  • 查看姓’张’的学生都有谁?

    SELECT name,job,gender,age
    FROM student
    WHERE name LIKE '张%'
    
  • 查看名字是以’晶’结尾的老师都有谁?

    SELECT name,title,salary
    FROM teacher
    WHERE name LIKE '%晶'
    
  • 查看三个字名字且最后一个字是’平’的学生都有谁?

    SELECT name,job,gender,age
    FROM student
    WHERE name LIKE '__平'
    
  • 查看三个字名字中第二个字符是’平’的学生都有谁?

    SELECT name,job,gender,age
    FROM student
    WHERE name LIKE '__平'
    
  • 查看职位是’什么课什么表’的学生都有谁?

    SELECT name,job,gender,age
    FROM student
    WHERE job LIKE '%课%表'
    
  • 查看所有2班都在哪层?

    SELECT name,floor
    FROM class
    WHERE name LIKE '%2班'
    

练习

1.查询名字姓"李"的学生姓名
  SELECT name,age
  FROM student
  WHERE name LIKE '李%'
  
2.查询名字中包含"江"的学生姓名
  SELECT name,age
  FROM student
  WHERE name LIKE '%江%'
  
3.查询名字以"郭"结尾的学生姓名
  SELECT name,age
  FROM student
  WHERE name LIKE '%郭'
  
4.查询9-12岁里是"课代表"的学生信息
  SELECT name,age,job
  FROM student
  WHERE age BETWEEN 9 AND 12
  AND job LIKE '%课代表'
  
5.查询名字第二个字是"苗"的学生信息
  SELECT name,age
  FROM student
  WHERE name LIKE '_苗%'
  
6.查询姓"邱"的课代表都是谁?
  SELECT name,job
  FROM student
  WHERE name LIKE '邱%'
  AND job LIKE '%课代表'

NULL值判断

  • 等于NULL:IS NULL
  • 不等于NULL:IS NOT NULL
  • 不能直接用=或<>判断NULL值

例:

  • 查看没有奖金的老师都有谁?(奖金字段值为null的记录)

    SELECT name,salary,comm
    FROM teacher
    WHERE comm=NULL
    上述SQL是查询不到任何记录的,因为comm的值不能用=来判断NULLSELECT name,salary,comm
    FROM teacher
    WHERE comm IS NULL
    
  • 查看有奖金的老师都有谁?

    SELECT name,salary,comm
    FROM teacher
    WHERE comm IS NOT NULL
    

ORDER BY子句

ORDER BY子句用于指定查询的结果集按照指定的字段进行排序

  • ORDER BY 字段名 [ASC] 将结果集按照指定的字段值升序排序(从小到大)
  • ORDER BY 字段名 DESC 将结果集按照指定的字段值降序排序(从大到小)
  • ORDER BY不指定排序方式时,默认为升序
  • ORDER BY 可以按照多字段排序:ORDER BY 字段1 ASC|DESC, 字段2… ASC|DESC
    • 多字段排序时,首先结果集按照第一个字段值的排序方式排序
    • 当第一个字段值相同的记录再按照第二个字段的排序方式继续排序
    • 以此类推
  • ORDER BY子句只能是DQL语句中的最后一个子句

例:

  • 查看老师工资的排名情况

    SELECT name,salary,title
    FROM teacher
    ORDER BY salary DESC
    
  • 查看老师的奖金情况,按照从少到多排序。

    SELECT name,comm
    FROM teacher
    ORDER BY comm
    
  • 查看学生的生日从远到近。

    日期字段排序是,越早的日期越小,越晚的日期越大。
    SELECT name,birth
    FROM student
    ORDER BY birth
    
  • 查看7-10岁学生名字,年龄,生日。查看时按照年龄从小到大。

    SELECT name,age,birth
    FROM student
    ORDER BY age,birth DESC
    
  • 查看老师的奖金和工资,按照奖金的升序,工资的降序

    SELECT name,comm,salary
    FROM teacher
    ORDER BY comm,salary DESC;
    

分页查询

当一条DQL语句可以查询出很多行记录时,为了减少资源开销,以及网络间的传送速度,我们通常都会使用分页查询来分批,分段的将DQL查询的结果集获取到。

分页是方言,标准SQL92标准中没有对分页的语法定义。

在MYSQL中分页使用LIMIT实现。在ORACLE中使用ROWNUM实现

语法:

在ORDER BY子句中使用LIMIT N,M

ORDER BY 字段 
LIMIT N,M
  • N表示跳过结果集的记录数

  • M表示从跳过N条记录后开始连续显示M条记录

  • 分页上两个条件:1:页数 2:每页显示的条数

    • N的公式:(页数-1)*每页显示的条数

    • M:每页显示的条数

    • 例如:一页显示15条,显示第3页?

      LIMIT (3-1)*15,15
      

例:

  • 查看老师工资排名的前5名是谁?

    SELECT name,salary
    FROM teacher
    ORDER BY salary DESC
    LIMIT 0,5
    
  • 按照老师奖金的降序排序后,每页显示3条,显示第5页

    - N的公式:(页数-1)*每页显示的条数
    - M:每页显示的条数
    SELECT name,comm
    FROM teacher
    ORDER BY comm DESC
    LIMIT 12,3
    

DQL中可以使用函数或者表达式进行查询

在SELECT子句中使用函数或表达式

使用表达式

例:

  • 查看每个老师的年薪是多少?

    SELECT name,salary,salary*12
    FROM teacher
    

使用函数

在计算表达式中,任何数字与NULL运算结果都是NULL

IFNULL(arg1,arg2)函数

  • 当arg1不为NULL时,函数返回arg1的值

  • 当arg1为NULL时,函数返回arg2的值

  • IFNULL作用时将一个NULL值换成一个非NULL值

  • 内部逻辑

    IFNULL(arg1,arg2){
    	if(arg1!=null){
    		return arg1;
    	}else{
    		return arg2
    	}
    }
    

例:

  • 查看每个老师的工资+奖金是多少?

    SELECT name,salary,comm,salary+comm
    FROM teacher
    上述SQL对于salary+comm而言,若comm字段为NULL时计算结果也为NULL
    
    SELECT name,salary,comm,IFNULL(comm,0)
    FROM teacher
    上述SQL会将comm字段为null的记录将该字段改为0
    
    查看老师工资+奖金的实际写法:
    SELECT name,salary,comm,salary+IFNULL(comm,0)
    FROM teacher
    

在WHERE子句中使用函数或表达式作为过滤条件

使用表达式

  • 查看年薪小于6万的老师都有谁?

    SELECT name,salary,salary*12
    FROM teacher
    WHERE salary*12<60000	查询时只有该条记录salary字段值*12小于60000的会被查出
    

使用函数

例:

  • 查看奖金小于3000的老师都有谁?

    比较运算时也会忽略NULL值的

    SELECT name,comm
    FROM teacher
    WHERE comm<3000
    上述查不出奖金字段为NULL的记录。
    
    SELECT name,comm
    FROM teacher
    WHERE IFNULL(comm,0)<3000
    

别名

  • 别名可以在SELECT子句中为函数,表达式取别名,是的结果集中该字段可读性更强。

  • 别名也可被用在其他子句上,比如在FROM子句中为表取别名,便于关联查询。

当SELECT子句中含有函数或表达式时,通常都会指定别名

语法

  • 字段名 别名

    SELECT salary*12 salary
    
  • 字段名 AS 别名

    SELECT salary*12 AS salary
    
  • 字段名 [AS] ‘字段名’

    SELECT salary*12 AS 'salary'SELECT salary*12 'salary'
    
  • 字段名 [AS] “字段名”

    SELECT salary*12 AS "salary"SELECT salary*12 "salary"
    
  • 当别名中含有SQL关键字或空格时要加引号

    SELECT name,salary*12 from     由于from是关键字,SQL语句语法错误(两次FROM)
    FROM teacher
    正确写法
    SELECT name,salary*12 'from'     
    FROM teacher
    
    下述SQL本意为salary*12取别名"annu sal"
    SELECT name,salary*12 annu sal   数据库理解annu为别名,再空格sal认为语法错误
    FROM teacher
    正确写法
    SELECT name,salary*12 'annu sal'
    FROM teacher
    
    

例:

  • 查看每个老师的年薪是多少?

    SELECT name,salary*12 salary
    FROM teacher
    

练习

1.查询所有10岁学生的生日,按生日对应的年纪从大到小.
  SELECT name,age,birth
  FROM student
  WHERE age=10
  ORDER BY birth
  
2.查询8岁同学中名字含有"苗"的学生信息
  SELECT name,age
  FROM student
  WHERE age=8
  AND name LIKE '%苗%'

3.查询负责课程编号12号且工资高于6000的老师信息
  SELECT name,salary,subject_id
  FROM teacher
  WHERE salary>6000
  AND subject_id IN (1,2)

4.查询10岁以上的语文课代表和数学课代表
  SELECT name,age,job
  FROM student
  WHERE age>10
  AND job IN ('语文课代表','数学课代表')

5.查询不教课程编号1的老师信息,按照工资降序排序
  SELECT name,salary,subject_id
  FROM teacher
  WHERE subject_id<>1
  ORDER BY salary DESC

6.查询没有奖金的老师信息
  SELECT name,comm
  FROM teacher
  WHERE IFNULL(comm,0)=0

7.查询所有老师的奖金,并按照奖金降序排序
  SELECT name,comm
  FROM teacher
  ORDER BY comm DESC

8.查看工资高于8000的老师负责的课程编号都有那些?
  SELECT DISTINCT subject_id
  FROM teacher
  WHERE salary>8000
  
9.查看全校年龄最小学生的第6-10SELECT name,age,birth
  FROM student
  ORDER BY birth DESC
  LIMIT 5,5

聚合函数

聚合函数(也称为多行函数,分组函数)是用来对结果集按照指定字段统计的。

聚合函数可以将多行记录中的指定字段统计出一条结果。

聚合函数:

  • MIN:统计结果集中指定字段值最小的
  • MAX:统计结果集中指定字段最大的
  • AVG:统计结果集中指定字段的平均值
  • SUM:统计结果集中指定字段的总和
  • COUNT:统计结果集中指定字段非空值共多少行
  • 聚合函数忽略NULL值的统计,在AVG和COUNT中最为明显

MIN,MAX,AVG,SUM是对字段值的统计。COUNT是对记录数的统计。

使用聚合函数时,通常要先将参与统计的记录查询出来后再决定添加何种聚合函数进行统计。

  • 查看所有老师的平均工资是多少?

    1:准备参与统计的记录对应的SQL语句
    下述SQL用来查询出所有老师的工资:
    SELECT salary
    FROM teacher
    
    2:为salary字段添加聚合函数,求所有记录salary的平均值
    SELECT AVG(salary)
    FROM teacher
    
    
    
  • 查看所有老师的最高工资,最低工资,工资总和和平均工资分别是多少?

    SELECT MAX(salary),MIN(salary),SUM(salary),AVG(salary)
    FROM teacher
    
  • 查看负责课程编号1的老师的平均工资是多少?

    1:查询出负责课程编号1的老师工资分别是多少?
    SELECT salary
    FROM teacher
    WHERE subject_id=1
    
    2:在上述SQL中对salary字段添加聚合函数求平均值
    SELECT AVG(salary)
    FROM teacher
    WHERE subject_id=1
    
  • 查看共有多少位老师?

    COUNT(*)作为统计被所有数据库都进行了优化,因此统计记录数时就用它

    SELECT COUNT(name)
    FROM teacher
    上述SQL统计结果共20条。teacher表中每条记录的name都有值
    
    SELECT COUNT(comm)
    FROM teacher
    上述SQL统计结果共17条。原因:teacher表中有3条记录comm字段值为NULL
    聚合函数是忽略NULL值的
    
    SELECT COUNT(*)
    FROM teacher
    
  • 查看所有老师的平均奖金

    SELECT AVG(comm),SUM(comm)
    FROM teacher
    上述SQL是对comm字段有的所有记录取平均值
    
    将NULL值替换为非NULL值再进行统计
    SELECT AVG(IFNULL(comm,0))
    FROM teacher
    
    
  • 查看负责课程编号1的老师共几人?

    SELECT COUNT(*)
    FROM teacher
    WHERE subject_id=1
    
  • 查看班级编号(class_id)为1的学生有多少人?

    SELECT COUNT(*)
    FROM student
    WHERE class_id=1
    
  • 查看全校学生生日最大的是哪天?

    SELECT MIN(birth)
    FROM student
    
  • 查看11岁的课代表总共多少人?

    SELECT COUNT(*)
    FROM student
    WHERE age=11
    AND job LIKE '%课代表'
    

GROUP BY子句,分组

GROUP BY子句在DQL语句中是对查询结果集按照指定的字段值相同的记录进行分组,配合聚合函数进行组内统计。

若DQL的SELECT子句中没有聚合函数时,不会使用GROUP BY子句。

在SELECT子句中不在聚合函数中的字段都必须出现在GROUP BY子句中

按照单字段分组

  • 教每门课程的老师的平均工资是多少?

    SELECT AVG(salary),subject_id
    FROM teacher
    GROUP BY subject_id
    
    GROUP BY子句的作用是将:
    SELECT salary,subject_id
    FROM teacher
    查询结果集按照subject_id字段值相同的记录分组,在组内统计结果。
    
  • 查看每个班级各多少学生?(将student表中所有记录按照class_id字段值相同的记录分组,组内统计记录数)

    SELECT COUNG(*),class_id
    FROM student
    GROUP BY class_id
    
  • 查看学校每种职位的学生各多少人?以及最大生日和最小生日

    SELECT COUNT(*) '人数',MIN(birth) '最大生日',MAX(birth) '最小生日',job
    FROM student
    GROUP BY job
    

按照多字段分组

GROUP BY子句若指定了多个字段,那么只有当这几个字段值都相同的记录才会被划分为一组。

  • 查看每个班每种职位各多少人?

    SELECT COUNT(*),job,class_id
    FROM student
    GROUP BY job,class_id
    

按照聚合函数排序

在SELECT子句中为聚合函数取别名,这样方便在ORDER BY子句中排序

  • 查看每个科目老师的平均工资,并按照平均工资从少到多排序

    SELECT AVG(salary),subject_id
    FROM teacher 
    GROUP BY subject_id
    ORDER BY AVG(salary)
    
    建议为聚合函数取别名,并按照该别名排序
    SELECT AVG(salary) avg,subject_id
    FROM teacher
    GROUP BY subject_id
    ORDER BY avg
    

HAVING子句,在分组统计时添加过滤条件

  • 仅查看平均工资高于6000的那些课程的老师平均工资

    SELECT AVG(salary),subject_id
    FROM teacher
    WHERE AVG(salary)>6000
    GROUP BY subject_id
    

    执行后报错:

请添加图片描述

聚合函数不能被应用与WHERE子句

原因:过滤实际不同

  • WHERE条件实在检索表中数据时,每检索一行记录就会进行一次WHERE,来决定该条记录是否被查询出来

  • 聚合函数想作为过滤条件(将统计结果作为过滤条件),统计的前提时要先查询出结果集,而查询结果集是WHERE的实际。因此根据统计结果再进行过滤应当已经是WHERE之后进行的了。

HAVING子句

HAVING子句仅跟在GROUP BY之后。因此若没有GROUP BY子句就不会写HAVING子句。

HAVING子句也是用于添加过滤条件的,过滤时机:分组统计出结果后进行二次过滤的。

HAVING子句是对分组过滤的:只有满足HAVING子句条件的分组才会进行SELECT中相应的统计。

WHERE子句是对记录过滤的:只有满足WHERE子句条件的记录才会进行SELECT中相应的查询

WHERE先执行,用于确定查询出的结果集。HAVING后执行用于确定保留结果集中的那些分组

  • 仅查看平均工资高于6000的那些课程的老师平均工资

    											子句执行顺序
    SELECT AVG(salary),subject_id               4:最后查询对应的内容(仅查询满足HAVING要求的组)
    FROM teacher								1:确定数据来自哪里
    GROUP BY subject_id							2:确定数据按照哪个字段分组(按照subject_id分6)
    HAVING AVG(salary)>6000                     3:确定仅保留哪些分组(仅有3组符合AVG要求)
    
  • 查看每个科目老师的平均工资,前提是该科老师最高工资高于9000.

    SELECT AVG(salary),subject_id       4:最后将过滤出的2组进行统计结果
    FROM teacher						1:确定数据来自teacher表
    GROUP BY subject_id                 2:按照subject_id字段值相同的可被分出6HAVING MAX(salary)>9000             3:分出的6组都要看最高工资是否>9000,最终过滤出2组。
    
  • 查看科目老师的工资总和是多少?前提是该科老师的平均奖金要高于4000.

    SELECT SUM(salary),subject_id
    FROM teacher
    GROUP BY subject_id
    HAVING AVG(IFNULL(comm,0))>4000
    

子查询

嵌套在其他SQL语句中的一条DQL语句就被称为子查询。

子查询使用场景

  • DQL中:可以基于一个查询结果集再进行查询(先执行的这条DQL就是子查询,也是子查询最常用的场景)
  • DML中:基于一个查询结果集进行增删改操作
  • DDL中:基于一个查询结果集进行数据库对象的操作(创建表,创建视图)

子查询分类

  • 单行单列子查询:查询结果集中只有一个值
  • 多行单列子查询:查询结果集中有多个值
  • 多行多列子查询:查询结果集就是一张表

在DQL语句中使用子查询

在DQL中子查询部分要被"()"括起来使用

例:

  • 查看哪个老师的工资高于王克晶的工资?

    1. 查询王克晶的工资是多少?

      SELECT salary 
      FROM teacher 
      WHERE name='王克晶'
      通过上述SQL我们可以得到一个单行单列的查询结果集:salary===>8000
      
    2. 查看谁的工资高于8000(王克晶的工资)?

      SELECT name,salary 
      FROM teacher 
      WHERE salary>8000
      
  1. 将步骤1的SQL替换为步骤2的8000

    示意: 
    int money = SELECT salary FROM teacher WHERE name='王克晶'    不是真实语法!!!
    查询示意:
    SELECT name,salary 
    FROM teacher 
    WHERE salary>money
    
    真实写法:
    SELECT name,salary 
    FROM teacher 
    WHERE salary>(SELECT salary 
                  FROM teacher 
                  WHERE name='王克晶')
    
    
    
  • 查看那些高于老师平均工资的老师工资都是多少?

    1:查看老师的平均工资是多少?
    SELECT AVG(salary)
    FROM teacher
    
    2:谁的工资高于平均工资?
    SELECT name,salary
    FROM teacher
    WHERE salary>(SELECT AVG(salary)
    			  FROM teacher)
    
  • 查看和’李费水’在同一个班的学生都有谁?

    1:查看‘李费水’所在班级的班级号
    SELECT class_id
    FROM student
    WHERE name='李费水'
    
    2:查看和'李费水'在同一个班的学生都有谁?
    SELECT name,class_id
    FROM student
    WHERE class_id=(SELECT class_id
    				FROM student
    				WHERE name='李费水')
    
  • 查看工资最高的老师的工资和奖金是多少?

    1:最高工资是多少?
    SELECT MAX(salary) FROM teacher
    
    2:查看工资最高的老师的工资和奖金是多少?
    SELECT name,salary,comm
    FROM teacher
    WHERE salary=(SELECT MAX(salary) FROM teacher)
    

** 在单行单列子查询中,若我们使用其作为过滤条件使用时,可以搭配:=, >, >=, <, <=, <>使用**

** 在多行单列子查询中(查询结果集有多个值),在过滤条件中要搭配:IN,ANY,ALL**

  • ANY与ALL是与:>, >=, <, <=联合使用的

    • >ANY(列表):大于列表其中之一(大于最小的即可)
    • <ANY(列表):小于列表其中之一(小于最大的即可)
    • >ALL(列表):大于列表所有(大于最大的)
    • <ALL(列表):小于列表所有(小于最小的)
  • IN(列表)或NOT IN(列表):在列表中或不在列表中

  • 上述所说的列表指的是一个多行单列子查询的结果集

  • 查看与"祝雷"和"李费水"在同一个班的学生都有谁?

    1:查看祝雷和李费水的班级号?
    SELECT class_id
    FROM student
    WHERE name IN('祝雷','李费水')
    
    2:查看与"祝雷""李费水"在同一个班的学生都有谁?
    SELECT name,class_id
    FROM student
    WHERE class_id=(SELECT class_id
                    FROM student
                    WHERE name IN('祝雷','李费水'))
    上述SQL执行后会报错,因为子查询返回了多个值,"="不能同时等于多个值           
    

请添加图片描述

正确写法:

SELECT name,class_id
FROM student
WHERE class_id IN(SELECT class_id
                  FROM student
                  WHERE name IN('祝雷','李费水'))
  • 查看比教科目2和科目4老师工资都高的老师都有谁?

    1:查看科目2和科目4老师的工资都是多少?
    SELECT salary FROM teacher WHERE subject_id IN(2,4)
    
    2:查看比教科目2和科目4老师工资都高的老师都有谁?
    SELECT name,salary,subject_id
    FROM teacher
    WHERE salary>ALL(SELECT salary 
                     FROM teacher 
                     WHERE subject_id IN(2,4))
    

在DML中使用子查询

例:

  • 将负责与"范传奇"教同一科目的所有老师工资涨500

    1:查看范传奇负责的科目号?
    SELECT subject_id
    FROM teacher
    WHERE name='范传奇'
    
    2:更新数据
    UPDATE teacher
    SET salary=salary+500
    WHERE subject_id=(SELECT subject_id
    				  FROM teacher
    				  WHERE name='范传奇')
    

在DDL中使用子查询

** 在创建表时,可以将一个子查询的结果集当作表创建出来。后期使用的视图也是如此。**

例:

  • 创建一张表用于记录老师工资的统计情况(按照科目)。要记录每门课老师的最高工资,最低工资,平均工资和工资总和以及科目编号。表名:teacher_salary_info

    1:创建表
    CREATE TABLE teacher_salary_info(
    	max_salary INT,
        min_salary INT,
        avg_salary INT,
        sum_salary INT,
        subject_id INT
    )
    2:先执行DQL查询对应结果,在使用DML中的INSERT语句逐行插入。
      若数据太多,工作量太大且笨重。
    SELECT MAX(salary),MIN(salary),AVG(salary),SUM(salary),subject_id
    FROM teacher
    GROUP BY subject_id
    
    实际写法:
    注意:如果子查询的SELECT子句中的字段是函数或表达式则必须要指定别名(会作为新创建的表的字段名)
    CREATE TABLE teacher_salary_info
    AS
    SELECT MAX(salary) max_sal,MIN(salary) min_sal,
           AVG(salary) avg_sal,SUM(salary) sum_sal,
           subject_id
    FROM teacher
    GROUP BY subject_id
    
    

关联查询(重点知识)

结果集中的字段来自于多张表。联合多张表进行查询。

表与表之间的数据存在着一种对应关系,这种对应关系被称为表与表之间的关联关系。

表之间的关联关系分为三种:

一对一:A表的一条记录仅对应B表的一条记录。反之亦然。

一对多:A表的一条记录对应B表的多条记录,反之B表的一条记录仅对应A表的一条记录。A与B是一对多的。

多对多:当两张表双向都是一对多时就是多对多关系。

在关联查询中必须要指定连接条件,连接条件作用是让数据库直到A表的记录与B表的哪些记录对应

关联查询中不指定连接条件会产生笛卡尔积,笛卡尔积通常是一个无意义的结果集(少数特殊业务除外)

多张表进行关联查询时,要满足当N张表联合查询时要指定最少N-1个连接条件。

  • 例如:3张表关联查询就至少要有2个连接条件。5张表关联查询就至少要有4个连接条件。

笛卡尔积

缺少连接条件产生笛卡尔积

特点:

以两张表A和B关联查询,结果集中包含的数据A表每条记录与B表每条记录产生的记录数。记录总数应当时A表记录数*B表记录数。

关联查询语法:

SELECT 字段...
FROM 表A,表B,...
WHERE 连接条件
AND 过滤条件
注意:如果在关联查询中含有过滤条件时必须与连接条件同时满足,否则会产生笛卡尔积

  • 查看类名老师的名字和其任课的科目名称?

    SELECT t.name,s.name
    FROM teacher t,subject s
    WHERE t.subject_id=s.id
    
    实际查询时,数据库会从teacher表中将其中一条记录与subject表中的每条记录都关联一次,但是仅将符合连接条件的记录分别取出查询的字段构成结果集中的一条记录。
    

请添加图片描述

请添加图片描述

  • 不指定连接条件时,可以通过结果集看出teacher表的每条记录都与subject表每条记录关联了一次产生一条结果(产生了笛卡尔积,记录数是teacher表的20条与subject表的5条的乘积,共100条记录!!!)

请添加图片描述

  • 查看班级的名称和对应的班主任(老师)是谁?

    1:数据需要来自哪些表?
    班级名称来自class表。老师名字来自teacher表。
    明确FROM子句内容:FROM class c,teacher t
    
    2:明确class表与teacher表记录之间的对应关系(关联关系)
    class表记录中teacher_id字段的值与teacher表记录中id字段的值相同的记录产生对应关系。
    明确WHERE子句连接条件:WHERE c.teacher_id=t.id
    
    SELECT c.name,t.name
    FROM class c,teacher t
    WHERE c.teacher_id=t.id
    
    
    
  • 查看每个学生的名字,年龄,以及其所在的班级名称和所在楼层

    1:确定数据来自哪些表?
    学生信息来自student表。班级信息来自class表
    明确FROM子句:FROM student s,class c
    
    2:student表与class表记录的对应关系?
    学生表某条记录的class_id值与class表某记录的id值相同的产生对应关系
    明确WHERE子句连接条件:s.class_id=c.id
    
    SELECT s.name,s.age,c.name,c.floor
    FROM student s,class c
    WHERE s.class_id=c.id
    
关联查询中可以指定过滤条件

过滤条件要与连接条件同时满足

  • "王克晶"是哪个班的班主任?查看班级名称,所在楼层和班主任名字以及工资

    SELECT c.name,c.floor,t.name,t.salary
    FROM class c,teacher t
    WHERE c.teacher_id=t.id
    AND t.name='王克晶'
    
  • 查看三年级的班级班主任都是谁?要列出班级名称,所在楼层,班主任名字和工资

    SELECT c.name,c.floor,t.name,t.salary
    FROM class c,teacher t
    WHERE c.teacher_id=t.id
    AND c.name LIKE '3年级%'
    
  • 查看5年级的中队长都有谁?要列出学生名字,年龄,性别,职位和所在班级的名字以及楼层

    SELECT s.name,s.age,s.gender,s.job,c.name,c.floor
    FROM student s,class c
    WHERE s.class_id=c.id		连接条件
    AND c.name LIKE '5年级%'     过滤条件
    AND s.job='中队长'			  过滤条件
    

N张表关联查询至少要有N-1个连接条件

  • 查看"范传奇"所带班级的学生都有谁?要列出:学生名字,年龄,班级名称,老师名字

    1:查询的数据来自哪些表
    学生信息来自student表。班级信息来自class表。老师信息来自teacher表
    明确FROM子句:FROM student s,class c,teacher t
    
    2:明确连接条件
      3张表关联至少要有2个连接条件
      2.1:学生表与班级表中的记录对应关系
      s.class_id=c.id
      2.2:班级表与老师表中的记录对应关系
      c.teacher_id=t.id
    
    3:过滤条件来自哪张表?
      老师名字叫"范传奇",来自teacher表
    
    SELECT s.name,s.age,c.name,t.name
    FROM student s,class c,teacher t
    WHERE s.class_id=c.id    连接条件
    AND c.teacher_id=t.id    连接条件    注:所有的连接条件要同时满足
    AND t.name='范传奇'       过滤条件
    
    
    

请添加图片描述

  • 查看1年级1班的同学的名字和来自的城市

    1:数据来自那些表
    城市信息来自location表。学生信息来自student表
    
    2:过滤条件来自哪些表?
    查看1年级1班的。条件来自class表。
    确定WHERE子句的过滤条件:c.name='1年级1班'
    
    上述两条联合确定
    FROM子句:FROM location l,student s,class c
    
    3:连接条件
      3.1:班级与学生的连接条件:c.id=s.class_id
      3.2:学生与城市的连接条件:s.location_id=l.id
    WHERE子句连接条件:WHERE c.id=s.class_id AND s.location_id=l.id 
    
    SELECT s.name,l.name  
    FROM location l,student s,class c
    WHERE c.id=s.class_id AND s.location_id=l.id 		连接条件
    AND c.name='1年级1班'								  过滤条件
    
    

练习:

1.查看来自北京的学生都是谁?
2."英语"的老师都是谁?
3.刘苍松所带班级的学生都有谁?
4.教语文的老师所带的班级有哪些?
5.王克晶所带的班级学生都来自哪些城市(去重)?
6.3年级的几个班主任都教哪些课程?
7.工资高于10000的老师所带班里的大队长都是谁?
8."李费水"的班主任教哪门课?
9.所在4楼的班里的大队长和中队长以及班主任都是谁?
10.全校最小的同学的班主任是谁?

HAVING和WHERE的区别

HAVEING : 后执行,过滤分组,仅在GROUP BY后

WHERE : 先执行, 过滤记录

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/31739.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

01.一个页面为啥有四个进程

打开了1个页面&#xff0c;Chrome启动了4个进程 并行处理 计算机中的并行处理就是同一时刻处理多个任务&#xff0c;比如我们要计算下面这三个表达式的值&#xff0c;并显示出结果。 A 12 B 20/5 C 7*8在编写代码的时候&#xff0c;我们可以把这个过程拆分为四个任务&…

sqli-labs/Less-57

这一关还是有14次尝试机会的 而且还是以id作为注入点的 首先输入如下语句 id1 and 12 查看回显 属于字符型 接着判断一下属于单引号还是双引号 输入1 查看回显 正确回显 在尝试一下双引号 输入1" 回显如下 肯定存在双引号包裹 但是是否有括号呢 不得而知 接着佐证一…

大一学生HTML期末作业 【html体育羽毛球6页面带注册】学生网页设计作业源码

⛵ 源码获取 文末联系 ✈ Web前端开发技术 描述 网页设计题材&#xff0c;DIVCSS 布局制作,HTMLCSS网页设计期末课程大作业 | 校园篮球网页设计 | 足球体育运动 | 体育游泳运动 | 兵乓球 | 网球 | 等网站的设计与制作 | HTML期末大学生网页设计作业 HTML&#xff1a;结构 CSS&…

【仿真建模】第五课:AnyLogic入门基础课程 - 地铁车站仿真讲解

文章目录一、新建模型二、修改相关属性三、OutPart 站外部分四、站内部分4.1 FirstFloor 第一层楼一、新建模型 新建模型&#xff0c;单位改为分钟 二、修改相关属性 修改比例尺 三、OutPart 站外部分 新建 OutPart 智能体类型 重命名为 OutPart 修改OutPart的比例尺为50&am…

【JVM】类加载机制:分析与验证

一、加载 将类的字节码载入方法区中&#xff0c;内部采用 C 的 instanceKlass 描述 java 类。它的重要 field 有&#xff1a; _java_mirror &#xff1a; java 的类镜像&#xff0c;例如对 String 来说&#xff0c;就是 String.class&#xff0c;作用是把 klass 暴露给 java 使…

直播预约|Flink + StarRocks 实时数据分析新范式

11月 26-27 日&#xff0c;Apache Flink &#xff08;以下简称 Flink&#xff09;社区官方技术大会 Flink Forward Asia 2022 将在线举行&#xff0c;聚集国内外一线厂商围绕 Flink 生态的生产实践经验进行分享。 本次大会上&#xff0c;StarRocks 将于 27 日 中午现身实时湖仓…

CSRF 漏洞学习笔记

什么是 CSRF 漏洞 CSRF&#xff08;Cross Site Request Forgery&#xff0c;跨站请求伪造&#xff0c;也叫 XSRF&#xff09;漏洞是由于未校验请求来源&#xff0c;导致攻击者可在第三方站点发起 HTTP 请求&#xff0c;并以受害者的目标网站登录态&#xff08;cookie、session…

ImmunoChemistry艾美捷自噬试验,红色解决方案

ImmunoChemistry艾美捷ICT的自噬测定&#xff0c;红色使研究人员能够检测和监测活细胞中自噬的体外发育。自噬探针是细胞渗透性的&#xff0c;插入自噬体和自溶体的脂质膜时发出红色荧光。可以使用流式细胞仪读取结果。 自噬是一种保守的溶酶体循环过程&#xff0c;细胞通过该过…

Linux——文件描述符(fd)与重定向、dup/dup2

目录 一.文件描述符 &#xff08;一&#xff09;.含义 &#xff08;二&#xff09;.使用 &#xff08;三&#xff09;.标准输入/输出/错误 二.重定向与dup/dup2 &#xff08;一&#xff09;.dup/dup2 &#xff08;二&#xff09;.重定向 一.文件描述符 &#xff08;一…

MCE | 淀粉样蛋白沉积或是阿尔茨海默症发展“驱动者”

近日&#xff0c;Cell 在线发表的论文 “Spatial Transcriptomics and In Situ Sequencing to Study Alzheimer’s Disease” 中&#xff0c;研究团队在 AD 小鼠模型中&#xff0c;利用空间转录组学研究淀粉样斑块周围直径 100 μm 的组织结构域的转录变化&#xff0c;证明了丰…

Web(二)html5基础-文档头部(知识训练和编程训练)

web知识训练_html5_文档头部标签及属性 web编程训练_html5_文档头部 第1关_页面标题及字符集的设置 <!DOCTYPE html> <html> <head><!-- ********* Begin ********* --><meta charset"utf-8"><title>设置标题</title>&…

《传统文化典藏馆》前端模板

一个基于多种插件的前端二次开发——弘扬中华传统文化的前端模板&#xff0c;内容丰富&#xff0c;可做学习前端技术使用。 主要技术实现&#xff1a;HTML、CSS、JavaScript 下载链接&#xff1a; 弘扬中华传统文化前端模板-Javascript文档类资源-CSDN下载《传统文化典藏馆》…

图像分割 - 分水岭算法

目录 1. 介绍 2. 分水岭算法的实现 距离变换 连接连通分量 3. 代码 1. 介绍 图像是由x&#xff0c;y表示的&#xff0c;如果将灰度值也考虑进去的话&#xff0c;那么一幅图像需要一个三维的空间去表示。 这样就可以把x&#xff0c;y轴比作大地&#xff0c;将灰度值的z轴…

产品流程图设计

一个产品设计之初&#xff0c;必先从流程图做起&#xff0c;流程图可以用来表达产品各式各样的流程&#xff0c;好的流程图&#xff0c;可以快速让整个团队熟悉理解业务&#xff0c;并优化业务。 一、常用的流程图图标含义 流程图通常由起止框、处理框、流程线、判断框、输出输…

使用HTML制作静态网站 中国传统文化 丝绸之路 (学生网页设计作业源码)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

HummerRisk V0.5.2:升级对象存储、云检测、云审计和K8s资源态势等

HummerRisk V0.5.2发布&#xff1a;对象存储增加风险检测和操作、云检测支持七牛云、操作审计支持 AWS&#xff0c;提升 K8s 资源态势&#xff0c;并支持在线/离线升级漏洞库。 感谢社区中小伙伴们的反馈&#xff0c;你们的认可是我们前进的动力。 HummerRisk 保持高速的迭代…

Web App、Hybrid App、Native App 横向对比

移动端的开发方式三分天下&#xff1a;纯原生&#xff08;Native App&#xff09;、混合开发&#xff08;Hybird App&#xff09;、网页应用&#xff08;Web App&#xff09;。 纯原生&#xff08;Native App&#xff09;&#xff1a;是在 Android、iOS 等移动平台上利用提供的…

2023第三届中国数字化人才国际峰会

会议背景 中商产业研究院预测&#xff0c;2022年我国数字经济规模将增至48.9万亿元&#xff0c;数字经济在GDP中的比重将超过40%。随着中国经济数字化转型不断深入的同时&#xff0c;数字化人才缺口却近1100万。中国信息通信研究院发布的《数字经济就业影响研究报告》指出&…

数学统计:均值、标准差、方差、协方差

均值:均值描述的是样本集合的中间点,它告诉我们的信息是很有限的。 标准差:标准差给我们描述的则是样本集合的各个样本点到均值的距离之平均。以这两个集合为例,[0,8,12,20]和[8,9,11,12],两个集合的均值都是10,但显然两个集合差别是很大的,计算两者的标准差,前…

蓝牙运动耳机什么品牌性价比高,六款值得推荐的运动耳机分享

音乐是运动健身的伴侣&#xff0c;两者合在一起就能让运动变得更加有劲。运动耳机怎么选&#xff0c;想要找到一款不错的运动耳机&#xff0c;首先一定要牢固舒适&#xff0c;其次防水性能越高越好&#xff0c;最后音质偏低音&#xff0c;如果在户外跑步的话&#xff0c;放着大…