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子句)
例
- 将张三的年龄改成20岁
- UPDATE person
- SET age=20
- WHERE name='张三' 仅将person表中某条记录name字段值为‘张三’的age改为20
-
- 将person表中年龄为16岁的人改为36岁
- UPDATE person
- Set age=36
- WHERE age=16 person表中凡是满足WHERE条件的记录都会被修改
WHERE子句中常用的条件
=, <, <= ,> ,>= ,<>(不等于使用<>。!=不是所有数据库都支持)
- 将person表中年龄大于30岁的人改为年龄29
- UPDATE person
- SET age=29
- WHERE age>30
将一个计算表达式的结果作为值使用
- 将person表中每个人的年龄涨1岁
- UPDATE person
- SET age=age+1 将每条记录年龄的值+1后再修改回年龄字段
同时修改多个字段
- 将'李四'改为'李老四'且年龄改为55岁
- UPDATE 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.修改刘备年龄为52岁
- UPDATE 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)
浮点类型: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)
日期类型
例
准备一张表测试各种类型
- 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)
例
- 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)
DQL是用于查询表中数据的语言。
语法:
- SELECT 子句
- FROM 子句
- WHERE 子句
- JOIN...ON...子句
- GROUP BY 子句
- HAVING 子句
- ORDER BY子句
一条DQL语句至少要包含的两个子句分别是SELECT子句和FROM子句
基础查询
由SELECT和FROM构成。
语法:
SELECT子句和FROM子句
- SELECT 字段1[,字段2,字段3,...]
- FROM 表1[,表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"或"来连接多个条件进行查询
例
查看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
3
DISTINCT去重操作。在结果集中去除指定字段值相同的记录
语法
- SELECT DISTINCT 字段1[,字段2,...]
- FROM 表名
- ...
例
查看老师的职称都有哪些?
- 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的男老师都有谁?
- 2.查看工资高于5000的女老师都有谁?
- 3.查看工资高于5000的男老师或所有女老师的工资?
- 4.查看所有9岁学生的学习委员和语文课代表都是谁?
-
- 5.查看工资在6000到10000之间的老师以及具体工资?
- 6.查看工资在4000到8000以外的老师及具体工资?
-
- 7.查看老师负责的课程编号都有什么?
- 8.查看所有女老师的职称都是什么?
-
- 9.查看7-10岁的男同学的职位都有哪些?
-
- 10.查看一级讲师和二级讲师的奖金(comm)是多少?
- 11.查看除老板和总监的其他老师的工资和奖金是多少?
- 12.查看'3年级2班'和'5年级3班'在那层楼?