数据库mysql操作语言, DDL,DML,DQL

news2024/10/7 8:22:40

文章目录

一. 数据库

1. 数据库基本概念

DataBase(数据库),存储数据的仓库。

之前我们项目中将用户信息写入一个文件,最终用一个目录users保存所有用户信息。这个users目录就可以称为

是一个数据库。利用文件系统进行操作,经常已手动或半自动形式维护数据的操作,缺点:低效。

2. 数据库管理系统

DBMS(数据库管理系统)。可独立运行的软件,用于维护数据的操作。

常见的DBMS有:

  • mysql
  • oracle
  • db2
  • sqlserver

请添加图片描述

3. 数据库与表的概念

以Mysql为例:

我们可以在Mysql中创建若干个数据库,每个数据库用于一个项目。

每个数据库中又可以创建多个表,表是用于保存一组数据的。

示意图:

请添加图片描述

数据表是由行和列构成

其中列被称为字段,就是一组数据中各部分信息。

其中行被称为记录,就是各部分信息组成的一条数据。

注:用面向对象的角度思考:

​ 表相当于是一个java类。比如User类

​ 字段相当于是类中的属性。比如User类中有username,password,nickname,age四个属性

​ 记录相当于是类的一个实例。比如一个User实例就可以表示一个用户信息
请添加图片描述

二. 连接数据库的方式

  1. 命令行形式
  2. 第一方或第三方提供的图形化界面的客户端
  3. 在集成开发环境中(IDEA,Eclipse)
  4. JDBC(java 数据库连接),java程序中若需要使用数据库则这样连接(IDEA,Eclipse都采取这种方式)

三. 如何操作DBMS

所有的DBMS都支持通过SQL语句进行操作。我们向数据库发送特定的SQL语句来表达要进行某项操作。

SQL有标准:SQL92

所有的DBMS都支持SQL92标准。

注:Structured Query Language(SQL)结构化查询语言

SQL语句分类

  • DDL 数据定义语言

    ​ CREATE,DROP,ALTER

    ​ 对数据库对象进行操作的语言。数据库对象有:数据库,表,视图,索引等。

  • DML 数据操作语言

    ​ INSERT,UPDATE,DELETE

    ​ 对表中的数据进行操作的语言。

  • DQL 数据查询语言

    ​ SELECT

    ​ 对表中的数据进行查询的语言。

  • DCL 数据控制语言

    ​ DBA用于管理数据库的语言。

  • TCL 事物控制语言

    ​ COMMIT,ROLLBACK

    ​ 对DML数据操作保证具有原子性,一致性。

1. DDL 数据定义语言

查看DBMS中已有的数据库

SHOW DATABASES

数据库相关操作

新建一个数据库

基本语法:

CREATE DATABASE 数据库名 [CHARSET=字符集名称]

例如:

新建一个名为mydb的数据库
CREATE DATABASE mydb

创建数据库时可以指定字符集

CREATE DATABASE mydb1 CHARSET=UTF8
CREATE DATABASE mydb2 CHARSET=GBK
查看数据库信息
SHOW CREATE DATABASE 数据库名

例:

SHOW CREATE DATABASE mydb1
删除数据库
DROP DATABASE 数据库名

例:

DROP DATABASE mydb1
使用一个数据库(切换一个数据库)

若希望保存数据,则数据必须保存在某张表上。而表必须保存在某个数据库上,因此后期为了对某个数据库的表进行操作,要先切换到该数据库上,才能进行操作。

USE 数据库名

例:切换到mydb数据库

USE mydb

练习:

1. 创建 mydb1和mydb2 数据库 字符集分别为utf8和gbk
   CREATE DATABASE mydb1 CHARSET=utf8
   CREATE DATABASE mydb2 CHARSET=gbk
2. 查询所有数据库检查是否创建成功
   SHOW DATABASES
3. 检查两个数据库的字符集是否正确
   SHOW CREATE DATABASE mydb1
   SHOW CREATE DATABASE mydb2
4. 先使用mydb2 再使用 mydb1
   USE mydb2
   USE mydb1
5. 删除两个数据库
   DROP DATABASE mydb1
   DROP DATABASE mydb2

表相关操作

创建表

语法:

CREATE TABLE 表名(
                 字段名 类型,
                 字段名 类型,
  ...
)

例:

CREATE TABLE user(
                   id INT,							INT在mysql中为整数类型。
    username VARCHAR(30),			VARCHAR在mysql中为字符串类型,长度为字节,
                     password VARCHAR(30),			VARCHAR(30)则字符转换的字节最多30个,
                     nickname VARCHAR(30),			若UTF-8编码则中文最多10个字(每个中文3字节)。
                     age INT(3)						INT指定长度为位数。这里INT(3)为最多3位整数。
)
查看已创建的表的表结构

语法:

DESC 表名

例:

查看user表的表结构
DESC user
查看已创建表的详细信息
SHOW CREATE TABLE 表名

例如:

SHOW CREATE TABLE user
删除表

语法:

DROP TABLE 表名

例:

删除userDROP TABLE user
查看数据库中所有的表
SHOW TABLES
修改表
  • 修改表名

    语法:

    RENAME TABLE 原表名 TO 新表名
    

    例如:

    将表user改名为userinfo
    RENAME TABLE user TO userinfo
    
  • 修改表结构

    准备一张表测试:
    CREATE TABLE hero(
      	name VARCHAR(30),
        age INT(3)
    ) 
    

请添加图片描述

  • 添加字段

    • 向表末尾追加新的字段

      ALTER TABLE 表名 ADD 字段名 类型
      

      例:

      ALTER TABLE hero ADD gender VARCHAR(10)
      

请添加图片描述

  • 将字段添加到表的第一个字段位置上
     ALTER TABLE 表名 ADD 字段名 类型 FIRST

例:

      在hero表第一个字段上添加id
      ALTER TABLE hero ADD id INT FIRST

请添加图片描述

  • 将字段插入到表中某个位置
     将字段插入到表中某字段的后面
     ALTER TABLE 表名 ADD 字段名 类型 AFTER 表中某字段

例:

      将密码(pwd)字段插入到name和age之间
      ALTER TABLE hero ADD pwd VARCHAR(30) AFTER name

请添加图片描述

  • 删除字段

    ALTER TABLE 表名 DROP 字段名
    

例:

   将pwd字段从hero表中删除
   ALTER TABLE hero DROP pwd
  • 修改现有字段
  ALTER TABLE 表名 CHANGE 原字段名 新字段名 类型

例:

     将hero表中age字段的长度改为5
     ALTER TABLE hero CHANGE age age INT(5)

请添加图片描述

     将hero表中age字段的类型改为VARCHAR(10)
     ALTER TABLE hero CHANGE age age VHARCHAR(10)

请添加图片描述

     将hero表中gender字段名改为pwd
     ALTER TABLE hero CHANGE gender pwd VARCHAR(10)

请添加图片描述

注意事项:

修改表字段应当在表中没有数据时进行。如果表中已经存在数据,则修改字段可能不成功。

比如:

hero表中有10条记录,每条记录gender字段已经有值(每个人的性别)

若此时将表字段gender修改类型为INT。此时字符串转换int("男"怎么转成整数???)


比如:

hero表中pwd记录了每个人的密码。原长度为10。此时若修改字段长度为5,会导致原密码保存不下则修改失败。

练习:

1.创建数据库mydb3 字符集gbk 并使用
  CREATE DATABASE mydb3 CHARSET=gbk
  USE mydb3
2.创建t_hero英雄表, 有名字和年龄字段
  CREATE TABLE t_hero(
  	name VARCHAR(30),
    age INT(3)
  ) 
3.修改表名为hero
  RENAME TABLE t_hero TO hero
4.查看表hero的信息
  SHOW CREATE TABLE hero
5.查询表hero结构
  DESC hero
6.删除表hero
  DROP TABLE hero
7.删除数据库mydb3
  DROP DATABASE mydb3

作业:

1.创建数据库mydb4 字符集utf8并使用
2.创建teacher表 有名字(name)字段
3.添加表字段: 最后添加age 最前面添加id(int) , age前面添加salary工资(int)
4.删除age字段
5.修改表名为t
6.删除表t
7.删除数据库mydb4

2. DML 数据操作语言

DML:对表中数据进行操作的语言,涵盖的内容为:INSERT(增),DELETE(删),UPDATE(改)

准备一张表:

CREATE TABLE person(
                     name VARCHAR(30),
                     age INT(3)
)

插入数据(INSERT)

语法:
INSERT INTO 表名[(字段1,字段2,...)] VALUES(字段的1,字段2的值,...)

注:在语法定义上"[]"中的内容表示可写可不写

INSERT INTO person(name,age) VALUES('张三',25)
  INSERT INTO person(age,name) VALUES(33,'李四')

注:

  • 数据库中字符串的字面量是使用单引号’'表达的

  • VALUES中指定的值要与指定的字段名个数,顺序,以及类型完全一致

  • 查看表中数据

    SELECT * FROM person
    
插入默认值

当插入数据时不指定某个字段,那么该字段插入默认值。若创建表时字段没有显示的指定默认值时,默认值插入NULL

例:

INSERT INTO person (name) VALUES ('王五')

请添加图片描述

注:

  • age字段没有指定,因此插入默认值NULL

  • 数据库中任何字段任何类型默认值都是NULL,当然可以在创建表时使用DEFAULT指定。

    修改person表中age的默认值为20
    ALTER TABLE person CHANGE age age INT(3) DEFAULT 20
    
    修改后向person表中插入数据
    INSERT INTO person (name) VALUES ('赵六')
    
    
    提示:也可在创建person表时为字段指定默认值
    CREATE TABLE person(
    	name VARCHAR(30) DEFAULT '无名氏',
        age INT(3) DEFAULT 20
    )
    

    为age添加默认值20:

请添加图片描述

插入’赵六’
请添加图片描述

全列插入

当我们插入数据是不指定任何字段名时,就是全列插入。此时VALUES子句中需要为每个字段指定值。并且要求(个数,顺序,类型必须与表完全一致)

例:

INSERT INTO person VALUES('钱七',21);

若某个字段有默认值,可以用DEFAULT表示默认值
INSERT INTO person VALUES('钱七',DEFAULT);

若某个字段想插入NULL值,可以使用NULL表达
INSERT INTO person VALUES('钱七',NULL);

下列为错误示例
INSERT INTO person VALUES('钱七');		列的值个数不匹配
INSERT INTO person VALUES(27,'钱七');		列的值类型不匹配

修改数据(UPDATE)

语法
UPDATE 表名 SET 字段1=新值1[,字段2=新值2,...][WHERE 过滤条件]

UPDATE person SET age=15
  上述SQL执行后会导致person表中所有记录的age字段值都被改为15

UPDATE语句通常都要添加WHERE子句,用于添加要修改记录的条件,否则全表修改!

修改指定记录(添加WHERE子句)

将张三的年龄改成20UPDATE person
SET age=20
WHERE name='张三'		仅将person表中某条记录name字段值为‘张三’的age改为20

将person表中年龄为16岁的人改为36UPDATE person
Set age=36
WHERE age=16		  person表中凡是满足WHERE条件的记录都会被修改
WHERE子句中常用的条件

=, <, <= ,> ,>= ,<>(不等于使用<>。!=不是所有数据库都支持)

将person表中年龄大于30岁的人改为年龄29
UPDATE person
SET age=29
WHERE age>30
将一个计算表达式的结果作为值使用
将person表中每个人的年龄涨1UPDATE person
SET age=age+1			将每条记录年龄的值+1后再修改回年龄字段
同时修改多个字段
'李四'改为'李老四'且年龄改为55UPDATE person
SET name='李老四',age=55
WHERE name='李四'

删除语句(DELETE)

语法:
DELETE FROM 表名 [WHERE 过滤条件]

注:DELETE语句通常都要添加WHERE子句,否则是清空表操作

例:

删除'李老四'
DELETE FROM person
WHERE name='李老四'	仅删除person表中满足WHERE条件的记录


删除年龄大于等于30岁的人
DELETE FROM person
WHERE age>=30

清空表操作
DELETE FROM person

练习:

1.创建数据库day1db 字符集utf8并使用
  CREATE DATABASE day1db CHARSET=utf8
  USE day1db
2.创建t_hero表, 有name字段,字符集utf8
CREATE TABLE t_hero(
  name VARCHAR(30)
)CHARSET=utf8
3.修改表名为hero
  RENAME TABLE t_hero TO hero
4.最后面添加价格字段money, 最前面添加id字段, name后面添加age字段
ALTER TABLE hero ADD money INT
ALTER TABLE hero ADD id INT FIRST
ALTER TABLE hero ADD age INT AFTER name
  
5.表中添加以下数据: 1,李白,50,6888 2,赵云,30,13888 3,刘备,25,6888
  INSERT INTO hero(id,name,age,money) VALUES(1,'李白',50,6888)
  INSERT INTO hero(id,name,age,money) VALUES(2,'赵云',30,13888)
  INSERT INTO hero(id,name,age,money) VALUES(3,'刘备',25,6888)
6.修改刘备年龄为52UPDATE hero
SET age=52
WHERE name='刘备'
  7.修改年龄小于等于50岁的价格为5000
UPDATE hero
SET money=5000
WHERE age<=50
  8.删除价格为5000的信息
DELETE FROM hero
WHERE money=5000
  9.删除表, 删除数据库
DROP TABLE hero
DROP DATABASE day1db

总结

  • DML:数据操作语言,它是对表中数据进行操作的语言,涵盖操作:增(INSERT),删(DELETE),改(UPDATE)

  • INSERT语句用于将数据插入表中

    • INSERT时指定的字段顺序可以与表不一致,但是VALUES子句中值的顺序要与指定顺序一致

    • INSERT时可以不指定某字段,那么此时该条记录该字段会插入默认值

    • INSERT时为某个字段插入其指定的默认值,使用关键字DEFAULT。

      字段若指定了默认值则使用该默认值,否则字段默认值为NULL。

    • INSERT时使用NULL插入一个字段为null值。

    • INSERT时可以不指定字段名,那么为全列插入,此时VALUES子句指定的值顺序,个数,类型必须与表结构完全一致。

  • UPDATE语句用于修改表中数据

  • DELETE语句用于删除表中数据

  • UPDATE语句和DELETE语句通常都要添加WHERE子句,否则是对全表所有记录操作。

数据库常用的数据类型

不同的数据库数据类型不完全一致

数字类型

整数类型:INT(m)和BIGINT(m)
  • m:整数的位数
  • int(5):最大保存一个5位整数。
    • 若保存的数字为18,实际存的时候前面会补0:00018
浮点类型:DOUBLE(m,n)
  • m:数字的位数

  • n:小数部分的位数

  • m包含n

    • DOUBLE(5,3):该数字总共5位,其中有3位小数(意味着整数位2位)。

      最大个保存的数字为:99.999

    • 当保存的数字精度超过可保存精度时,会进行4舍5入

      例如person表中salary字段的类型:DOUBLE(7,4)

      INSERT INTO person (salary) VALUES(553.12568)
      实际salary保存的数字为:553.1257

    请添加图片描述

    • 当最大值需要进行四舍五入时,此时会报错:值超出了范围

请添加图片描述

字符类型

定长字符:CHAR(n)
  • n表示长度,单位是字符。

  • name CHAR(10):name可以保存10个字符

  • 最大值为255个字符

  • 表中该字段保存数据时,实际在磁盘中保存数据一定是指定长度的字符。当实际保存的字符不足时会补充空格来达到长度。

    例如:name插入数据时为’张三’。那么实际存储时后面还有8个空格要占够10个字符。

  • 优点:每条记录占用的字节长度是固定的,这对于数据库扫描磁盘查询数据时效率高。

  • 缺点:浪费磁盘空间

变长字符:VARCHAR(n)
  • n表示长度,单位时字节。

  • 最大值为65535个字节

  • 表中该字段保存数据时,实际在磁盘中保存数据用多少占多少字节。

    例如:name VARCHAR(30)

    插入数据时name为’张三’,实际存储时磁盘中仅6个字节。

  • 优点:不浪费磁盘空间

  • 缺点:查询速度慢

变长字符:TEXT(n)
  • n表示长度,单位是字符
  • 最大值为65535

日期类型

  • DATE:仅保存年月日
  • TIME:时分秒
  • DATETIME:保存年月日时分秒
  • TIMESTAMP:时间戳,记录UTC时间。自1970-01-01 00:00:00到表达的时间所经过的毫秒

  • 准备一张表测试各种类型

    CREATE TABLE userinfo(
    	id INT,
    	username VARCHAR(30),
    	gender CHAR(1),
    	birth DATETIME,
    	salary DOUBLE(7,2)
    )
    
  • 插入日期时,可以以字符串形式插入,格式为:“yyyy-MM-dd hh:mm:ss”

    注:MM表示两位数字的月,mm表示两位数字的分

    INSERT INTO userinfo(id,username,gender,birth,salary)
    VALUES (1,'张三','男','2001-02-03 12:22:55',5000.99)
    
  • 插入日期时,如果类型为DATETIME,插入字符串中可以不指定时分秒

    INSERT INTO userinfo(id,username,gender,birth,salary)
    VALUES (2,'李四','女','1998-08-24',6000)
    此时时分秒都为0
    

请添加图片描述

  • DATETIME类型插入数据时不能忽略年月日

    INSERT INTO userinfo(id,username,gender,birth,salary)
    VALUES (3,'王五','男','12:15:32',5000)
    会报错,DATETIME字段不能只插入时分秒
    

请添加图片描述

  • 插入DOUBLE值时精度超过部分会四舍五入,整数部分若超过长度则会报错

    INSERT INTO userinfo(id,username,gender,birth,salary)
    VALUES (3,'王五','男','1985-06-01 12:15:32',100000)
    

约束条件

可以对表添加约束条件,这样一来仅当满足约束条件的操作才可以进行。这样做可以更好的为我们的业务服务,保证数据库的操作是服务业务要求的。

主键约束(PRIMARY KEY)

  • 主键的特点:非空且唯一。符合该特点的值才可以用来标识表中唯一的一条记录。
  • 通常一张表中的第一个字段都是主键字段,名字通常选取为:id
  • 主键约束一张表只能为一个字段添加

CREATE TABLE user1(
                    id INT PRIMARY KEY,
                    name VARCHAR(30),
                    age INT(3)
);

INSERT INTO user1(id,name,age) VALUES (1,'张三',22)
  INSERT INTO user1(id,name,age) VALUES (2,'李四',33)
  • 主键字段不能插入重复的值

请添加图片描述

  • 主键字段不能插入NULL值

请添加图片描述

  • 不能修改重复的值

请添加图片描述

  • 不能修改为NULL

** 具体主键约束的字段通常会配合自增(AUTO_INCREMENT)使用**

  • 将字段定义为主键约束时,同时指定:AUTO_INCREMENT

    CREATE TABLE user2(
        id INT PRIMARY KEY AUTO_INCREMENT,
        name VARCHAR(30),
        age INT(3)
    );
    
    也可以修改现有的表字段
    ALTER TABLE user1 CHANGE id id INT PRIMARY KEY AUTO_INCREMENT
    
  • 当主键字段具有自增功能时,插入数据则可以忽略主键字段的插入

 INSERT INTO user2 (name,age) VALUES('张三',22)
 INSERT INTO user2 (name,age) VALUES('李四',33)
  • 当显示的给自增字段插入NULL值时,该字段的值仍然会自增。(不推荐)
  INSERT INTO user2 (id,name,age) VALUES(NULL,'王五',36)

非空约束(NOT NULL)

被非空约束修饰的字段表中每条记录该字段必须有值,不能为NULL

CREATE TABLE user3(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(30) NOT NULL,
	age INT(3)
)

  • 非空约束在查看表结构时有所体现

    DESC user3
    

请添加图片描述

  • 不能将NULL值插入具有非空约束的字段中

    INSERT INTO user3 (name,age) VALUES(NULL,22)
    
  • 插入数据时不能忽略具有非空约束的字段(字段默认插入NULL)

    INSERT INTO user3(age) VALUES(33)
    

请添加图片描述

3. 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/30274.html

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

相关文章

HOOPS/MVO技术概述

更多参见&#xff1a;HOOPS学习笔记 MVO 1.引言 HOOPS/MVO是一个C类库&#xff0c;位于HOOPS 3D图形系统&#xff08;HOOPS/3DGS&#xff09;之上。它有一个模型/视图/操作员架构&#xff0c;封装了各种HOOPS/3DGS数据结构和概念&#xff0c;并提供了一系列通用应用程序级逻辑…

【无人机】基于粒子群优化干扰受限下无人机群辅助网络附matlab代码

✅作者简介&#xff1a;热爱科研的Matlab仿真开发者&#xff0c;修心和技术同步精进&#xff0c;matlab项目合作可私信。 &#x1f34e;个人主页&#xff1a;Matlab科研工作室 &#x1f34a;个人信条&#xff1a;格物致知。 更多Matlab仿真内容点击&#x1f447; 智能优化算法 …

Xception --tensorflow2.x

简介 Xception和SqueezeNet一样&#xff0c;是一种降低参数量的轻量级神经网络&#xff0c;它主要使用了 深度分离卷积&#xff08;Depthwise separable convolution)结构&#xff0c;该结构替换了原来的Inception中的多尺寸卷积结构。这里需要弄清深度分离卷积&#xff08;D…

【创建型设计模式-单例模式】一文搞懂单例模式的使用场景及代码实现的7种方式

1.什么是单例模式 在了解单例模式前&#xff0c;我们先来看一下它的定义&#xff1a; 确保一个类只有一个实例&#xff0c;而且自行实例化并且自行向整个系统提供这个实例&#xff0c;这个类称为单例类&#xff0c;它提供全局访问的方法&#xff0c; 单例模式是一种对象的创建型…

微型计算机原理速通期末复习

文章目录微机基础原码、反码、补码、移码溢出实数型功能结构8086/8088内部结构80286内部结构80386/80486内部结构标志寄存器FLAGS寄存器阵列段寄存器寻址标志寄存器EFLAGS分段结构数据寻址方式立即寻址直接寻址寄存器寻址寄存器间接寻址寄存器相对寻址基址-变址寻址基址-变址-相…

Solidity vs. Vyper:不同的智能合约语言的优缺点

本文探讨以下问题&#xff1a;哪种智能合约语言更有优势&#xff0c;Solidity 还是 Vyper&#xff1f;最近&#xff0c;关于哪种是“最好的”智能合约语言存在很多争论&#xff0c;当然了&#xff0c;每一种语言都有它的支持者。 这篇文章是为了回答这场辩论最根本的问题&…

磨金石教育摄影技能干货分享|中国风摄影大师——郎静山

说到中国风摄影&#xff0c;你想到的画面是什么样子的&#xff1f;故宫、长城、苏州园林、大红灯笼高高挂&#xff0c;反正离不开传承了千八百年的古建筑。仿佛没有了这些历史古董的元素就没有中国味道似的。 其实中国风&#xff0c;其内核应该是传统的审美观念和哲学思想。中…

【雷丰阳-谷粒商城 】课程概述

持续学习&持续更新中… 学习态度&#xff1a;守破离 【雷丰阳-谷粒商城 】课程概述该电商项目与其它项目的区别项目简介项目背景电商模式谷粒商城项目技术&特色项目前置要求谷粒商城-微服务架构图谷粒商城-微服务划分图参考该电商项目与其它项目的区别 互联网大型项目…

深入linux内核架构--内存管理

【推荐阅读】 代码大佬的【Linux内核开发笔记】分享&#xff0c;前人栽树后人乘凉&#xff01; 一文了解Linux内核的Oops 一篇长文叙述Linux内核虚拟地址空间的基本概括 路由选择协议——RIP协议 深入理解Intel CPU体系结构【值得收藏&#xff01;】 内存体系结构 1. UM…

银行测试人员谈测试需求

今天呢&#xff0c;想用故事说话&#xff0c;先看看啥叫用户需求挖掘。其实看完故事之后&#xff0c;我自己颇为震撼&#xff0c;请看。 故事一&#xff1a; 100多年前&#xff0c;福特公司的创始人亨利福特先生到处跑去问客户&#xff1a;“您需要一个什么样的更好的交通工具…

loganalyzer 展示数据库中的日志

1 实验目标&#xff1a; 利用rsyslog日志服务&#xff0c;将收集的日志记录于MySQL中&#xff0c;通过loganalyzer 展示数据库中的日志 2 环境准备 三台主机&#xff1a; 一台日志服务器&#xff0c;利用上一个案例实现&#xff0c;IP&#xff1a;192.168.100.100一台数据库…

【Java八股文总结】之数据结构

文章目录数据结构一、概念1、时间复杂度与空间复杂度2、常见算法时间复杂度3、Comparable二、常见的排序算法1、直接插入排序2、希尔排序3、选择排序4、堆排序5、冒泡排序6、快速排序7、归并排序8、二分查找算法Q&#xff1a;什么时候需要结束呢&#xff1f;三、线性表1、概念2…

使用 Footprint Analytics, 快速搭建区块链数据应用

Nov 2022, danielfootprint.network 如果你有一个处理 NFTs 或区块链的网站或应用程序&#xff0c;你可以在你的平台上直接向用户展示数据&#xff0c;以保持他们在网站或者应用内的参与&#xff0c;而不是链接以及跳出到其他网站。 对于任何区块链应用或者媒体、信息网站来说…

秦皇岛科学选育新品种 国稻种芯·中国水稻节:河北秸秆变肥料

秦皇岛科学选育新品种 国稻种芯中国水稻节&#xff1a;河北秸秆变肥料 秦皇岛新闻网 记者李妍 冀时客户端报道&#xff08;河北台 张志刚 米弘钊 赵永鑫 通讯员 赵力楠&#xff09; 新闻中国采编网 中国新闻采编网 谋定研究中国智库网 中国农民丰收节国际贸易促进会 国稻种芯…

无线通信技术概览

电生磁&#xff0c;磁生电 电场和磁场的关系&#xff0c;简而言之就是&#xff1a;变化的电场产生磁场&#xff0c;变化的磁场产生电场。 电荷的定向移动产生电流&#xff0c;电荷本身产生电场。电流是移动的电场。静止的电荷产生静止的电场&#xff0c;运动的电荷产生运动的电…

java实现阿里云rocketMQ消息的发送与消费(http协议sdk)

目录一、准备工作二、代码实现1.添加依赖2.创建一个常量类存放公共参数3.调用HTTP协议的SDK 发送普通消息4.调用HTTP协议的SDK 订阅普通消息三、配置main的日志输出级别四、测试效果五、完成代码一、准备工作 登录阿里云官网&#xff0c;先申请rocketMQ&#xff0c;再申请Topi…

一文带你了解PCB设计中的常用基本概念

本文将从初学者的角度出发&#xff0c;一文带你快速了解PCB设计中的常用基本概念&#xff1a;一、FR4板材FR-4就是玻璃纤维环氧树脂覆铜板&#xff0c;线路板中的一种基材&#xff0c;可以分为一般FR4板材和高TG FR4板材&#xff0c;Tg是玻璃转化温度&#xff0c;即熔点。电路板…

分享好玩的h5小游戏制作_为什么要做h5微信小游戏呢

近年来&#xff0c;市面上一直流行各种h5游戏&#xff0c;例如投票、答题、刮刮乐、大转盘等等等等&#xff0c;而且我在各种营销场景下经常看到它们的身影&#xff0c;是做促销&#xff0c;引流和宣传的神器之一&#xff01; 那么&#xff0c;怎么做好玩的h5游戏&#xff1f;还…

DIXml v5.21.0 for Delphi 11

DIXml v5.21.0 for Delphi 11 DIXml是一个嵌入式XML、XSLT&#xff0c;也是Delphi的EXSLT处理库(Embarcadero//CodeGear/Borland)。它构建在libxml2、libxslt和libexslt库上&#xff0c;但不需要更多的DLL或其他外部文件。 DIXml很容易成为Delphi中功能最齐全的XML和XSLT替代品…

实战讲解MyBatis缓存:一级缓存和二级缓存(图+文+源码)

1 缘起 回顾SpringBoot如何进行事务管理相关知识的时&#xff0c; 发现使用Spring的注解Transational即可实现事务管理&#xff0c;完成回滚操作&#xff0c; 然而SpringBoot中使用MyBatis这个ORM框架操作数据库&#xff0c;实现CURD&#xff0c; 这两者有什么关系呢&#xff…