1.创建、修改和删除
表是数据库存储数据的基本单位、一个表包含若干个字段或记录、表的操作包括创建新表、修改表和删除表。这些操作都是数据库管理中最基本,也是最重要的操作。在这一章中将讲解如何在数据库中操作表。
- 创建表方法
- 表的完整性约束条件
- 查看表结构的方法
- 修改表的方法
- 删除表的方法
1.1 创建表方法
创建表是指在已存在的数据库中建立新表。这是建立数据库最重要的一步,是进行其他操作的基础。
1.1.1 创建表的语法形式
MySQL中,创建表是通过SQL语句CREATE TABLE实现的。
CREATE TABLE 表名(
属性名 数据类型 [完整性约束条件],
属性名 数据类型 [完整性约束条件],
......
属性名 数据类型 [完整性约束条件],
)[表类型] [表字符集];
SQL是不区分大小写
命名规范:
1. 命名富有意义(英文或英文组合)
2. 自定义名称使用小写
3. MySQL语句使用大写
1. mysql -h localhost -u root -p
2. SHOW DATABASES;
3. CREATE DATABASE IF NOT EXISTS example
4. CREATE TABLE IF NOT EXISTS text1 (
id INT,
name VARCHAR(20);
gender BOOLEAN,
) Engine = MyISAM;
5. DESCRIBE test1 \g -- 查看example表的结构
完整性约束条件表
PRIMARY KEY 标识该属性为该表的主键,可以唯一的标识对应的元组
FOREIGN KEY 标识该属性为该表的外键,是与之联系的某表的主键
NOT NULL 标识该属性不能为空
UNIQUE 标识该属性的值是唯一的
AUTO_INCREMENT 标识该属性的值自动增加,这是MySQL的SQL语句的特色(null,0)
DEFAULT 标识该属性设置默认值(not null defualt 0,not null default 0.0,not null default '')
id INT UNSIGNED NOT NULL AUTO_INCREMENT PRIMAKRY KEY,
name VARCHAR(20) NOT NULL DEFUALT '',
height DOUBLE(10,2) NOT NULL DEFAULT 0.00,
age INT NOT NULL DEFUALT 0,
sex CHAR(4) NOT NULL DEFAULT '男',
1.1.2 设置表的主键
主键是表的一个特殊字段。该字段能惟一地标识该表中的每条信息。主键和记录的关系,如同身份证和人的关系。主键用来标识每个记录,每个记录的主键值都不同。身份证是用来标明人的身份,每个人都具有惟一的身份证号。设置表的主键指在创建表时设置表的某个字段为该表的主键。
主键的主要目的是帮组MySQL以最快的速度查找到表中的某一条信息。
主键必须满足的条件:
1. 主键必须是唯一的,表中任意两条记录的主键字段的值不能相同;
2. 主键的值是非空值;
3. 主键可以是单一的字段,也可以是多个字段组合。
1. 单字段的主键:
CREATE TABLE student1 (
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20) NOT NULL,
stu_gender BOOLEAN
) Engine = InnoDB;
SHOW TABLES;
DESCRIBE student1;
2. 多字段主键:
CREATE TABLE student2 (
stu_id INT,
course_id INT,
grade FLOAT,
PRIMARY KEY(stu_id, course_id)
)Engine = InnoDB;
1.1.3 设置表的外键
外键是表的一个特殊字段。如果字段sno是一个表A的属性,且依赖于表B的主键。那么,称表B为父表,表A为子表,sno为表A的外键。通过sno字段将父表B和子表A建立关联关系。设置表的外键指在创建表设置某个字段为外键。
设置外键的原则:必须依赖于数据库中已存在的父表的主键;外键可以为空值。
外 键的作用: 是建立该表与其父表的关联关系。父表中删除某条信息时,子表中与之对应的信息也必须有相应的改变。例如,stu_id就student表的主 键,stu_id是grade表的外键。当stu_id为'123'同学退学了,需要从student表中删除该学生的信息。那么,grade表中 stu_id为'123'的所有信息也应该同时删除。
CONSTRAINT 外键别名 FOREIGN KEY (属性1.1, 属性1.2...属性1.n);
REFERENCES 表名(属性2.1, 属性2.2,...,属性2.n)
CREATE TABLE student3 (
id INT PRIMARY KEY,
stu_id INT,
course_id INT,
# 设置外键
CONSTRAINT C_fk FOREIGN KEY(stu_id, course_id) REFERENCES student2(stu_id, course_id)
) Engine = InnoDB;
1.1.4 设置表的非空约束
非 空性是指字段的值不能为空值(NULL)。非空约束将保证所有记录中该字段都有值。如果用户新插入的记录中,该字段为空值,则数据库系统会报错。例如,在 id字段加上非空约束,id字段的值就不能为空。如果插入记录的id字段的值为空,该记录将不能插入。设置表的非空约束是指在创建表时为表的某些特殊字段 加上NOT NULL约束条件。设置非空约束的基本语法规则如下:
属性名 数据类型 NOT NULL
CREATE TABLE student4 (
id INT NOT NULL PRIMARY KEY,
name VARCHAR(20) NOT NULL,
stu_id INT,
CONSTRAINT d_fk FOREIGN KEY(stu_id) REFERENCES student2(stu_id)
);
1.1.5 设置表的唯一性约束
惟 一性是指所有记录中该字段的值不能重复出现。设置表的惟一性约束是指在创建表时为表的某些特殊字段加上UNIQUE约束条件。唯一性约束将保证所有记录中 该字段的值不能重复出现。例如,在id字段加上惟一性约束,所以记录中id字段上不能出现相同的值。例如,在表的id字段加上惟一性约束,那么每条记录的 id值都是惟一的,不能出现重复的情况。如果一条的记录的id值都是惟一的,不能出现重复的情况。如果一条的记录的id为'0001',那么该表中就不能 出现另一条记录的id为'0001'。设置惟一性约束的基本语法规则如下:
属性名 数据类型 UNIQUE
CREATE TABLE student5 (
id INT NOT NULL PRIMARY KEY,
stu_id INT UNIQUE,
name VARCHAR(20) NOT NULL
);
INSERT INTO `student5` values(1, 10, 'Sue'), (2, 11, 'Lucy');
INSERT INTO `student5` values(2, 10, 'Jack');
1.1.6 设置表的属性值自动增加
AUTO_INCREMENT 是MYSQL数据库中一个特殊的约束条件。其主要用于为表中插入的新记录自动生成惟一的ID。一个表只能有一个字段使用AUTO_INCREMENT约 束,且该字段必须为主键的一部分。AUTO_INCREMENT约束的字段可以是任何整数类型(TINYINT、SMALLINT、INT、BIGINT 等)。默认情况下,该字段的值是从1开始自增。
设置属性值字段增加的基本语法规则如下:
属性名 数据类型 AUTO_INCREMENT
CREATE TABLE student6 (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
stu_id INT UNIQUE,
name VARCHAR(20) NOT NULL
);
INSERT INTO `student6` values('', 10, 'Sue'), ('', 11, 'Lucy');
INSERT INTO `student6` values('', 12, 'Jack');
1.1.7 设置表的履的默认值
在创建表时可以指定表中字段的默认值。如果插入一条新的记录时没有为这个字段赋值,那么数据库系统会自动为穿上字段插入默认值。默认值通过DEFAULT关键字来设置的。
属性名 数据类型 DEFAULT 默认值
CREATE TABLE student7 (
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
stu_id INT UNIQUE,
name VARCHAR(20) NOT NULL DEFAULT 'WHAT',
language VARCHAR(20) DEFAULT 'cn',
english VARCHAR(20) DEFAULT 'ZERO',
math FLOAT DEFAULT 0,
computer FLOAT DEFAULT 0
);
INSERT INTO `student7` VALUES('',10,'Sue', 'kr', 'one','','');
INSERT INTO `student7` VALUES('',11,'Jack', '', '','','');
1.2 查看表结构
查看表结构是指查看数据库中已存在的表的定义。查看表结构的语句包括DESCRIBE语句和SHOW CREATE TABLE语句。通过这两个语句,可以查看表的字段名、字段的数据类型、完整性约束条件等。
1.2.1 查看表基本结构语句DESCRIBE
MySQL中,DESCRIBE语句可以查看表的基本定义。其中包括、字段名、字段数据类型、是否为主键和默认值等。
DESCRIBE 表名;
DESC或DESCRIBE student7;
1.2.2 查看表详细结构语句SHOW CREATETABLE
MySQL中,SHOW CREATE TABLE语句可以查看表的详细定义。该语句可以查看表的字段名、字段的数据类型、完整性约束条件等信息。除此之外,还可以查看表默认的存储引擎和字符编码。SHOW CREATE TABLE语句的语法形式如下:
SHOW CREATE TABLE 表名;
SHOW CREATE TABLE student7;
1.3 修改表的方法
修 改表是指修改数据库中已存在的表。修改表比重新定义表简单,不需要重新加载数据,也不会影响正在进行的服务。MySQL中能过ALTER TABLE [alter:改变,更改]语句来修改表。修改表包括修改表名、修改字段数据类型、修改字段名、增加字段、删除字段、修改字段的排列位置、更改表的存储引 擎和删除表的外键约束等。
1.3.1 修改表名
表 名可以在一个数据库中唯一的确定一张表。数据库系统通过表名来区分不同的表。例如,数据库school中有student表。那么student表就是唯 一的。在数据库school中不可能存在另一个名为"student"的表。MySQL中,修改表名是通过SQL语句ALTER TABLE实现的。其语法形式如下:
ALTER TABLE 旧表名 RENAME [TO] 新表名;
实例一:
CREATE TABLE student8 (
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20) NOT NULL,
stu_gender BOOLEAN
) Engine = InnoDB;
SHOW TABLES;
DESCRIBE student8;
ALTER TABLE student8 RENAME TO student8_changed;
1.3.2 修改字段的数据类型
字 段的数据类型包括整型、浮点数型、字符串型、二进制类型、日期和时间类型等。数据类型决定了数据的存储格式、约束条件和有效范围。表中每个字段都有数据类 型。ALTER TABLE语句也可以修改字段的数据类型。其基本语法如下:ALTER TABLE 表名 MODIFY 属性名 数据类型;
实例一:
CREATE TABLE student9 (
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
content VARCHAR(20) NOT NULL,
stu_gender BOOLEAN
) Engine = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE student9 MODIFY stu_name char(20);
1.3.3 修改字段名[字段的数据类型, 完整性约束条件]
字 段名可以在一张表中唯一确定一个字段。数据库系统通过字段名来区分表中的不同字段。例如,student表中包含id字段。那么,id字段在 student表中是唯一的。student表中不可能存在另一个名为"id"的字段。MySQL中ALTER TABLE语句也可以修改表的字段名。其基本语法如下:
ALTER TABLE 表名 CHNAGE 旧字段名 新字段名 新数据类型 [新完整性约束条件];
其中,"旧字段名"参数指修改前的字段名;"新字段名"参数指修改后的字段名;"新数据类型"参数修改后的数据类型,如不需要修改,则将新类型设置成与原来一样。
1. 只修改字段名
2. 修改字段名和字段数据类型
3. 修改完整性约束条件
实例一:
CREATE TABLE student10 (
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
content VARCHAR(20) NOT NULL,
stu_gender BOOLEAN
) Engine = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE student10 CHANGE stu_name stu_name_changed VARCHAR(20);
ALTER TABLE student10 CHANGE content content_changed VARCHAR(50) NOT NULL DEFAULT 'XXXX';
1.3.4 增加字段
在创建表时,表中的字段就已经定义完成。如果要增加新的字段,可以通过ALTER TABLE语句进行增加。
MySQL中,ALTER TABLE语句增加字段的基本语法如下:
ALTER TABLE 表名 ADD 新字段名 数据类型 [完整性约束条件] [FIRST | AFTER 已有字段名];
1. 增加无完整性约束条件的字段
2. 增加有完整性约束条件的字段
3. 表的第一个位置增加字段
4. 表的指定位置之后增加字段
实例一:
CREATE TABLE student11 (
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
content VARCHAR(20) NOT NULL,
stu_gender BOOLEAN
) Engine = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE student11 ADD phone VARCHAR(20);
ALTER TABLE student11 ADD birthday TIMESTAMP NOT NULL;
ALTER TABLE student11 ADD num INT(11) NOT NULL FIRST;
ALTER TABLE student11 ADD address VARCHAR(30) NOT NULL AFTER phone;
1.3.5 删除字段
删 除字段是指删除已经定义好的表中的某个字段。在表创建好之后,如果发现某个字段需要删除。可以采用将整个表都删除,如果发现某个字段需要删除。可以采用将 整个表都删除,然后重新创建一张表的做法。这样做是可以达到目的,但必须会影响到表中的数据。而且,操作比较麻烦。MySQL中,ALTER TABLE语句也可以删除表中的字段。其基本语法如下:
ALTER TABLE 表名 DROP 字段名;
实例一:
CREATE TABLE student12 (
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
content VARCHAR(20) NOT NULL,
stu_gender BOOLEAN
) Engine = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE student12 DROP `content`;
1.3.6 修改字段的排列位置
创 建表的时候,字段在表中的排列位置就已经确定了。如果要改变字段在表中的排列位置,则需要ALTER TABLE语句来处理。MySQL中,修改字段排列位置的ALTER TABLE语句的基本语法如下:ALTER TABLE 表名 MODIFY 字段名 数据类型 FIRST | AFTER 字段名2;
1. 字段修改到第一个位置
2. 字段修改到指定位置
实例一:
CREATE TABLE student13 (
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
content VARCHAR(20) NOT NULL,
stu_gender BOOLEAN
) Engine = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE student13 MODIFY content VARCHAR(20) FIRST;
ALTER TABLE STUDENT13 MODIFY stu_id INT AFTER stu_name;
1.3.7 更改表的存储引擎
MySQL 存储引擎是指MySQL数据库中表的存储类型。MySQL存储引擎包括InnoDB、MyISAM、MEMORY等。不同的表类型有着不同的优缺点。在创 建表的时候,存储引擎就已经设定好了。如果要改变,可以通过重新创建一张表来实现。这样做是可以达到目的,但必然会影响到表中的数据。而且,操作比较麻 烦。
ALTER TABLE 表名 ENGINE=存储引擎名;
实例一:
CREATE TABLE student14 (
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
content VARCHAR(20) NOT NULL,
stu_gender BOOLEAN
) Engine = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE student14 ENGINE=MyISAM;
1.3.8 删除表的外键约束
外键是一个特殊字段,其将某一个表与其父表建立关系关系。在创建表的时候,外键约束就已经设定好了。由于特殊需要,与父表之间的关系关系需要去除,要求删除外键约束。MySQL中,ALTER TABLEy语句也可以删除表的外键约束。
ALTER TABLE 表名 DROP FOREIGN KEY 外键别名;
实例一:
CREATE TABLE `student15` (
`id` INT NOT NULL PRIMARY KEY,
`name` VARCHAR(20) NOT NULL,
`stu_id` INT,
CONSTRAINT st_fk FOREIGN KEY(stu_id) REFERENCES student7(stu_id)
) Engine = InnoDB ;
ALTER TABLE `test`.`student15` DROP FOREIGN KEY st_fk;
1.4 删除表的方法
删除表是指删除数据库已经存在的表。删除表时,会删除表中的所有数据。因此,在删除表时特别注意。MySQL中通过DROP TABLE语句来删除表。由创建表时可能存在外键约束,一些表成为了与之关联的表的父表。要删除这些父表,情况比较复杂。
1.4.1 删除没有关系的普通表和被其他关联的父表的方法。
CREATE TABLE student16 (
stu_id INT PRIMARY KEY,
stu_name VARCHAR(20) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
content VARCHAR(20) NOT NULL COMMENT '内容',
stu_gender BOOLEAN
) Engine = InnoDB CHARACTER SET utf8 COLLATE utf8_general_ci;
DROP TABLE [IF EXISTS] student16;
1.4.2.删除被其他表关联的父表
数据库中某些表之间建立了关联关系。一些表成为了父表,这些表被其子表关联着。要删除这些父表,情况不像上一节那么简单。
CREATE TABLE `test`.`student17_parent` (
`id` INT NOT NULL PRIMARY KEY,
`stu_id` INT,
`name` VARCHAR(20) NOT NULL
) Engine = InnoDB ;
CREATE TABLE `student17_child` (
`id` INT NOT NULL PRIMARY KEY,
`stu_id` INT UNIQUE,
`name` VARCHAR(20) NOT NULL,
CONSTRAINT parent_fk FOREIGN KEY(stu_id) REFERENCES student17_parent(id) -- id必须是带有索引
) Engine = InnoDB;
DROP TABLE `student17_parent`; -- 不能删除,因为与这关联的表有外键
# 先删除外键,然后就可以删除表student17_parent
ALTER TABLE `student17_child` DROP FOREIGN KEY parent_fk;
DROP TABLE `student17_parent`;
2.查询数据
查询数据指从数据库中获取所需要的数据。查询数据是数据库操作中最常用,也是最重要操作。用户可能根据自己对数据的需求,使用不同的查询方式。通过不同的查询方式,可以获得不同的数据。MySQL中是使用SELECT语句来查询数据的。
- 查询语句的基本语法
- 在单表上查询数据
- 使用聚合函数查询数据
- 多表上联合查询
- 子查询
- 合并查询结果
- 为表和字段取别名
- 使用正则表达式查询
2.1 基本查询语句
查 询数据是数据库操作中最常用的操作。通过对数据库的查询,用户可以从数据库中获取需要的数据。数据库中可能包含着无数的表,表中可能包含着无数记录。因 此,要获得所需的数据并非易事。MySQL中可以使用SELECT语句来查询数据。根据查询的条件的不同,数据库系统会找到不同的数据。通过SELECT 语句可以很方便的获取所需的信息。
MySQL中,SLEECT的基本语法形式如下:
SELECT 属性列表
FROM 表名和视图列表
[WHERE 条件表达式1]
[GROUP BY 属性名1] [HAVING 条件表达式2]
[ORDER BY 属性名[ASC|DESC]]
'属性列表'参数表示需要查询的字段名;
'表名或视图列表'参数表示此处指定的表或者视图中查询数据,表和视图可以有多个;
'条件表达式1'参数指定查询条件;
'属性名1'参数指按该字段中的数据进行分组;
'条件表达式2'参数表示满足该表达式的数据才能输出;
'属性名2'参数指按该字段中的数据进行排序,排序方式由'ASC'和'DESC'两个参数指出;
'ASC'参数表示按升序的顺序进行排序,这是默认排序;(从小到大)
'DESC'参数表示按降序的顺序进行排序。(从大到小)
如果有WHERE子句,就按照'条件表达式1'指定的条件进行查询。如果没有WHERE子句,就查询所有记录。
如果有GROUP BY子句,就按照'属性名1'指定的字段进行分组。如果GROUP BY子句后带着HAVING关键字,那么只有满足'条件表达式2'中指定的条件才能够输出。
GROUP BY子句通常和COUNT()、SUM()等聚合函数一起使用。
如果有ORDER BY子句,就按照'属性名2'指定的字段进行排序。排序方式由'ASC'和'DESC'两个参数指出。默认的情况下是'ASC'。
CREATE TABLE employee(
num INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
d_id INT NULL,
name VARCHAR(20),
age INT,
gender VARCHAR(4),
homeaddr VARCHAR(50)
) DEFAULT CHARSET=utf8;
INSERT INTO employee VALUES
(NULL, 1001, '张三', 26, '男', '北京市海淀区'),
(NULL, 1001, '李四', 24, '女', '北京市昌平区'),
(NULL, 1002, '王五', 25, '男', '湖南长沙市'),
(NULL, 1004, 'Aric', 15, '男', 'England');
(1)使用SELECT语句查询employee表
select num, name, age, gender, homeaddr FROM employee;
(2)包括WHERE子句和ORDER BY子句的SELECT语句
SELECT num, d_id, name, age, gender, homeaddr
FROM employee
WHERE age<26
ORDER BY d_id DESC;
2.2 单表查询
单 表查询是指从一张表中查询所需要的数据。查询数据时,可以从一张表中查询数据,也可以从多张表中同时查询数据。两者的查询方式有一定的区别。因为单表查询 只在一张表上进行操作,所以查询比较简单。本小节将讲解在单表上查询所有的字段、查询指定的字段、查询指定的行、多条查询、查询结果不重复、给查询结果排 序、分组查询和用LIMIT限制查询结果的数据等内容。
2.2.1 查询所有字段
查询所有字段是指查询表中所有字段的数据。这种方式可以将表中所有字段的数据都查询出来。MySQL中有两种方式可以查询表中所有的字段。
1. 列出表的所有字段
2. 使用'*'查询所有字段
(1)SELECT语句查询employe表中的所有字段的数据
SELECT num, d_id, name, age, gender, homeaddr FROM employee;
(2)用SELECT语句来查询employee表的所有字段的数据,此处用'*'来代替'属性列表'。
SELECT * FROM employee;
2.2.2 查询指定字段
查询数据时,可以在SELECT语句的'属性列表'中列出所有查询的字段。这种方式可以指定需要查询的字段,而不需要查询出所有的字段。下面查询employee表中num、name、gender和homeaddr这四个字段的数据。
SELECT num, name, gender, homeaddr FROM employee;
2.2.3 查询指定记录
SELECT 语句中可以设置查询条件。用户可以根据自己的需要来设置查询条件,按条件进行查询。查询的结果必须满足查询条件。例如,用户需要查找d_id为1001的 记录,那么可以设置'd_id=1001'为查询条件。这样查询结果中的记录就都会满足'd_id=1001'这个条件。WHERE子句可以用来指定查询 条件。
WHEER 条件表达式
(1)查询employee表中d_id为1001的记录。
SELECT * FROM employee WHERE d_id=1001;
(2)查询employee表中d_id为1004的记录。
SELECT * FROM employee WHERE d_id=1004;
2.2.4 带IN关键字的查询
IN关键字可以判断某个字段的值是否在指定的集合中。如果字段的值在集合中,则满足查询条件,该记录被查询出来。如果不在集合中,则不满足查询条件。其语法规则如下:
[NOT] IN(元素1, 元素2,...,元素n)
查询条件 符号或关键字
比较 =, <, <=, >, >=, !=, <>, !>, !<
指定范围 BETWEEN AND, NOT BETWEEN AND
指定集合 IN, NOT IN
匹配字符 LIKE, NOT LIKE
是否为空值 IS NULL, IS NOT NULL
多个查询条件 AND, OR
(1)使用IN关键字查询。
SELECT * FROM employee WHERE d_id IN(1001,1004);
(2)使用NOT IN关键字查询, 而且集合元素为字符型数据。
SELECT * FROM employee WHERE name NOT IN('张三','李四');
2.2.5 带BETWEEN AND的范围查询
BETWEEN AND关键字可以判断某个字段的值是否在指定的范围内。如果字段的值在指定范围内,则满足查询条件,该记录将被查询出来。如果不在指定范围内,则不满足查询条件。其语法规则如下:
[NOT] BETWEEN 取值1 AND 取值2
(1)使用BETWEEN AND关键字进行查询,查询条件是age字段取值从15到25。
SELECT * FROM employee WHERE age BETWEEN 15 AND 25;
(2)使用NOT BETWEEN AND关键字查询employee表。查询条件是age字段的取值不在15到25之间。
SELECT * FROM employee WHERE age NOT BETWEEN 15 AND 25;
2.2.6 带LIKE的字符匹配查询
LIKE关键字可以匹配字符串是否相等。如果字段的值与指定的字符串相匹配,则满足查询条件,该记录将被查询出来。如果与指定的字符串不匹配,则不满足查询条件。其语法规则如下:
[NOT] LIKE '字符串'
SELECT * FROM employee WHERE name LIKE 'Aric';
SELECT * FROM employee WHERE homeaddr LIKE '北京%';
SELECT * FROM employee WHERE name LIKE 'Ar_c';
SELECT * FROM employee WHERE homeaddr LIKE '%区';
2.2.7 查询空值
IS NULL 关键字可以用来判断字段的值是否为空值(NULL)。如果字段的值是空值,则满足查询条件,该记录将被查询出来。如果字段的值不是空值,则不满足查询条件。其语法规则如下:
IS [NOT] NULL
其中,'NOT'是可选参数,加上NOT表示字段不是空值时满足条件。
CREATE TABLE work(
id INT,
name VARCHAR(20),
gender VARCHAR(4),
info VARCHAR(50)
) DEFAULT CHARSET=utf8;
INSERT INTO work VALUES
(1001, 'hijh', NULL, NULL),
(1002, 'CCH', NULL, NULL),
(1003, 'zk', NULL, 'student');
SELECT * FROM work WHERE info IS NULL;
SELECT * FROM work WHERE info IS NOT NULL;
2.2.8 带AND的多条件查询
AND关键字可以用来联合多个条件进行查询。使用AND关键字时,只有同时满足所有查询条件记录会被查询出来。如果不满足这些查询条件的其中一个,这样的记录将被排除掉。AND关键字的语法规则如下:
条件表达式1 AND 条件表达式2 [... AND 条件表达式n]
其中,AND可以连接两个条件表达式。而且,可以同时使用AND关键字,这样可以连接更多的条件表达式。
SELECT * FROM employee
WHERE d_id<1004
AND gender LIKE '男';
SELECT * FROM employee
WHERE d_id<1004
AND age<26 and="" gender="男" select="" from="" employee="" where="" num="" in="" 1="" 2="" 3="" and="" age="" between="" 15="" and="" 25="" and="" homeaddr="" like="" 10="" 2="" 9="" or="" or="" and="" or="" or="" 1="" or="" 2="" or="" n="" or="" or="" select="" from="" employee="" where="" num="" in="" 1="" 2="" 3="" or="" age="" between="" 24="" and="" 25="" or="" homeaddr="" like="" select="" from="" employee="" where="" num="" in="" 1="" 3="" 4="" and="" age="25" or="" gender="女" select="" from="" employee="" where="" gender="女" or="" num="" in="" 1="" 3="" 4="" and="" age="25;" 10="" 2="" 10="" employee="" d_id="" select="" distinct="" d_id="" from="" employee="" 10="" 2="" 11="" order="" by="" order="" by="" asc="" desc="" select="" from="" employee="" ordery="" by="" age="" select="" from="" employee="" order="" by="" age="" asc="" select="" from="" employee="" order="" by="" age="" desc="" select="" from="" employee="" order="" by="" d_id="" asc="" age="" desc="" 10="" 2="" 12="" group="" by="" group="" by="" having="" with="" rollup="" 1="" group="" by="" 2="" group="" by="" group_concat="" 3="" group="" by="" 4="" group="" by="" having="" 5="" 6="" group="" by="" with="" rollup="" select="" from="" employee="" group="" by="" gender="" select="" gender="" group_concat="" name="" from="" employee="" group="" by="" gender="" select="" gender="" count="" gender="" from="" employee="" group="" by="" gender="" select="" gender="" count="" gender="" from="" employee="" group="" by="" gender="" having="" count="" gender="">=3;
INSERT INTO employee VALUES(NULL, 1002, '赵六', 22, '男', '延吉市开发区');
SELECT * FROM employee GROUP BY d_id, gender;
SELECT gender, COUNT(gender) FROM employee GROUP by gender WITH ROLLUP;
SELECT gender, GROUP_CONCAT(name) FROM employee GROUP BY gender WITH ROLLUP;
2.2.9 用LIMIT限制查询结果的数量
查 询数据时,可能会查询出很多的记录。而用户需要的记录可能只是很少的一部分。这样就需要来限制查询结果的数量。LIMIT是MySQL中的一个特殊关键 字。其可以用来指定查询结果从哪条记录开始显示。还可以指定一共显示多少条记录。LIMIT关键字有两种使用方式。这两种方式分别是不指定初始位置和指定 初始位置。
1. 不指定初始位置
2. 指定初始位置
SELECT * FROM employee LIMIT 2;
SELECT * FROM employee LIMIT 6;
SELECT * FROM employee LIMIT 0, 2;
SELECT * FROM employee LIMIT 2, 2;
2.3 使用集合函数查询
集 合函数包括COUNT()、SUM()、AVG()、MAX()和MIN()。其中,COUNT()用来统计记录的条件;SUM()用来计算字段的值的总 和;AVG()用来计算字段的值的平均值;MAX()用来查询字段的最大值;MIN()用来查询字段的最小值。当需要对表中的记录求和、求平均值、查询最 大值、查询最小值等操作时,可以使用集合函数。例如,需要计算学生成绩表中的平均成绩,可以使用AVG()函数。GROUP BY关键字通常需要与集合函数一起使用。
2.3.1 COUNT函数
COUNT()函数用来统计记录的条数。如果要统计employee表中有多少条记录,可以使用COUNT()函数。如果要统计employee表中不同部门的人数,也可以使用COUNT()函数。使
SELECT COUNT(*) FROM employee;
SELECT d_id, COUNT(*) from employee GROUP BY d_id;
2.3.2 SUM()函数
SUM()函数是求和函数。使用SUM()函数可以求出表中某个字段取值的总和。例如,可以用SUM()函数来求学生的总成绩。
CREATE TABLE grade(
num INT NOT NULL,
course VARCHAR(10) NOT NULL,
score FLOAT
) DEFAULT CHARSET=utf8;
INSERT INTO grade VALUES
(1001, '数学', 80),
(1001, '语文', 90),
(1001, '英语', 85),
(1001, '计算机', 95),
(1002, '数学', 88),
(1002, '语文', 90),
(1002, '英语', 89),
(1002, '计算机', 90),
(1003, '数学', 80),
(1003, '语文', 98),
(1003, '英语', 85),
(1003, '计算机', 95);
SELECT * FROM grade WHERE num=1001;
SELECT num, SUM(score) FROM grade WHERE num=1001;
SELECT num, SUM(score) FROM grade GROUP BY num;
2.3.3 AVG()函数
AVG()函数是求平均值的函数。使用AVG()函数可以求出表中某个字段取值的平均值。例如,可以用AVG()函数来求平均年龄,也可以使用AVG()函数来求学生的平均成绩。
SELECT AVG(age) FROM employee;
SELECT course, AVG(score) FROM grade GROUP BY course;
SELECT num, AVG(score) FROM grade GROUP BY num;
2.3.4 MAX()函数
MAX()函数是求最大值的函数。使用MAX()函数可以求出表中某个字段取值的最大值。例如,可以用MAX()函数来查询最大年龄,也可以使用MAX()函数来求各科的最高成绩。
SELECT MAX(age) FROM employee;
SELECT num, course, MAX(score) FROM grade GROUP BY course;
SELECT MAX(name) from work;
2.3.5 MIN()函数
MIN()函数是求最小值的函数。使用MIN()函数可以求出表中某个字段取值的最小值。例如,可以用MIN()函数来查询最小年龄,也可以使用MIN()函数来求各科的最小成绩。
SELECT MIN(age) FROM employee;
SELECT num, course, MIN(score) FROM grade GROUP BY course;
SELECT MIN(name) from work;
2.4 连接查询
连 接查询是将两个或两个以上的表按某个条件连接起来,从中选取需要的数据。连接查询是同时查询两个或两个以上的表时使用的。当不同的表中存在表示相同意义的 字段时,可以通过该字段来连接这几个表。例如,学生表中有course_id字段来表示所学课程的课程号,课程表中有num字段来表示课程号。那么,可能 通过学生表中的course_id字段与课程表中的num字段来进行连接查询。连接查询包括内连接查询和外连接查询。本小节将详细讲解内连接查询和外连接 查询。同时,还会讲解多个条件结合在一起进行复合连接查询。
2.4.1 内连接查询
内连接查询是一种最常用的连接查询。内连接查询可以查询两个或两个以上的表。当两个表中存在表示相同意义的字段时,可以通过该字段来连接这两个表。当该字段的值相等时,就查询出该记录。
INSERT INTO department VALUES
(1004, '人力资源部', '管理员工的信息', '2号楼3层');
INSERT INTO employee VALUES(NULL, 1003, '刘花', 28, '女', '吉林省长春市');
INSERT INTO employee VALUES(NULL, 1006, '王晶', 22, '女', '吉林省通化市');
使用内连查询的方式查询
SELECT num, name, employee.d_id, age, d_name, function
FROM employee, department
WHERE employee.d_id=department.d_id;
2.4.2 外连接查询
外连接查询可以查询两个或两个以后的表。外连接查询也需要通过指定字段来进行连接。当该字段取值相等时,可以查询该记录。而且,该字段取值不相等的记录也可以查询出来。外连接查询包括左连接查询和右连接查询。其基本语法如下:
SELECT 属性名列表
FROM 表名1 LEFT|RIGHT JOIN 表名2
ON 表名1.属性名1 = 表名2.属性名2;
1. 左连接查询
SELECT num, name, employee.d_id,age,gender, d_name, function
FROM employee
LEFT JOIN department
ON employee.d_id=department.d_id;
2. 右连接查询
SELECT num, name, employee.d_id,age,gender, d_name, function
FROM employee
RIGHT JOIN department
ON employee.d_id=department.d_id;
CREATE TABLE performance(
id INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
e_num INT(10) NOT NULL UNIQUE,
performance FLOAT NOT NULL DEFAULT 0
) DEFAULT CHARSET=utf8;
INSERT INTO performance VALUES
(NULL, 2, 2000),
(NULL, 1, 100),
(NULL, 3, 5000),
(NULL, 5, 8000),
(NULL, 6, 10000);
SELECT num, name, employee.d_id,age,gender, d_name, function, performance
FROM employee
LEFT JOIN department
ON employee.d_id=department.d_id
LEFT JOIN performance
ON employee.num=performance.id;
2.4.3 复合条件连接查询
在连接查询时,也可以增加其他的限制条件。通过多个条件的复合查询,可以使查询结果更加准备。例如,employee表和department表进行连接查询时,可以限制age字段的取值必须大于24。可以更加准备的查询出年龄大于24岁的员工的信息。
SELECT num,name,employee.d_id,age,gender,d_name,function
FROM employee,department
WHERE employee.d_id=department.d_id
AND age>24
ORDER BY age DESC;
2.5 子查询
子 查询是将一个查询语句嵌套在另一个查询语句中。内层查询语句的查询结果,可以为外层查询语句提供查询条件。因为在特定情况下,一个查询语句的条件需要另一 个查询语句来获取。例如,现在需要从学生成绩表中查询计算机系统学生的各科成绩。那么,首先就必须知道哪些课程是计算机系学生选修的。因此,必须先查询计 算机系学生选修的课程,然后根据这些课程来查询计算机系学生的各科成绩。通过子查询,可以实现多表之间的查询。子查询中可能包括IN、NOT IN、ANY、ALL、EXISTS、NOT EXISTS等关键字。子查询中还可能包含比较运算符,如'='、'!='、'>'和'<'等。
2.5.1 带IN关键字的子查询
一 个查询语句的条件可能在另一个SELECT语句的查询结果中。这可以通过IN关键字来判断。例如,要查询哪些同学选择了计算机系开设的课程。先必须从课程 表中查询出计算机系开设了哪些课程。然后再从学生表中进行查询。如果学生选修的课程在前面查询出来的课程中,则查询出该同学的信息。这可以用带IN关键字 的子查询来实现。
SELECT * FROM employee
WHERE d_id IN(SELECT d_id FROM department);
SELECT * FROM employee
WHERE d_id NOT IN(SELECT d_id FROM department);
2.5.2 带比较运算符的子查询
子查询可以使用比较运算符。这些比较运算符包括=、!=、>、>=、<、<=、<>等。其中,<>与!=是等价的。比较运算符在子查询时使用的非常广泛。如查询分数、年龄、价格、 收入等。
CREATE TABLE computer_stu(
id INT PRIMARY KEY,
name VARCHAR(20),
score FLOAT
) DEFAULT CHARSET=utf8;
INSERT INTO computer_stu VALUES(1001, 'lILY', 85);
INSERT INTO computer_stu VALUES(1002, 'Tom', 91);
INSERT INTO computer_stu VALUES(1003, 'Jim', 87);
INSERT INTO computer_stu VALUES(1004, 'Aric', 77);
INSERT INTO computer_stu VALUES(1005, 'Lucy', 65);
INSERT INTO computer_stu VALUES(1006, 'Andy', 99);
INSERT INTO computer_stu VALUES(1007, 'Ada', 85);
INSERT INTO computer_stu VALUES(1008, 'jeck', 70);
CREATE TABLE scholarship(
level INT PRIMARY KEY,
score INT
) DEFAULT CHARSET=utf8;
INSERT INTO scholarship VALUES(1, 90);
INSERT INTO scholarship VALUES(2, 80);
INSERT INTO scholarship VALUES(3, 70);
在computer_stu表中查询获得一等奖学金的学生的学号、姓名和分数。各个等级的奖学金的最低存储在scholarship表中。
SELECT id, name, score, FROM computer_stu
WHERE score>=(SELECT score FROM scholarship WHERE level=1)
在department表中查询哪些部门没有年龄为24岁的员工。员工的年龄存储在employee表中。先查询一下employee表和deparment表,以便进行对比。
SELECT d_id, d_name
FROM department
WHERE d_id!=(SELECT d_id FROM employee WHERE age=24);
SELECT d_id, d_name
FROM department
WHERE d_id<>(SELECT d_id FROM employee WHERE age=24);
2.5.3 带EXISTS关键字的子查询
EXISTS 关键字表示存在。使用EXISTS关键字时,内层查询语句不返回查询的记录。而是返回一个真假值。如果内层查询语句查询到满足条件的记录,就返回一个真值 (TRUE)。否则,将返回一个假值(FALSE)。当返回的值是真值时,外层查询语句将进行查询。当返回值是假值时,外层查询语句不再进行查询或者查询 不出任何记录。
如果department表中存在d_id取值为1003的记录,则查询employee表的记录
SELECT * FROM employee
WHERE EXISTS(SELECT d_name FROM department WHERE d_id=1003);
如果department表中存在d_id取值为1003的记录,则查询employee表中age大于24的记录
SELECT * FROM employee
WHERE age>24 AND EXISTS(SELECT d_name FROM department WHERE d_id=1006);
如果department表中不存在d_id取值为1003的记录,则查询employee表的记录
SELECT * FROM employee
WHERE NOT EXISTS(SELECT d_name FROM department WHERE d_id=1006);
2.5.4 带ANY关键字的子查询
ANY 关键字表示满足其中任一条件。使用ANY关键字时,只要满足内层查询语句返回的结果中的任何一个,就可以通过该条件来执行外层查询语句。例如,需要查询哪 些同学能够获得奖学金。那么,首先必须从奖学金表中查询出各种奖学金要求的最低分。只要一个同学的成绩高于不同奖学金最低分的任何一个,这个同学就可以获 得奖学金。ANY关键字通常与比较运算符一起使用。
从computer_stu表中查询哪些同学可以获得奖学金。奖学金的信息存储在scholarship表中。
SELECT * FROM computer_stu WHERE score>=ANY
(SELECT score FROM scholarship);
2.5.5 带ALL关键字的子查询
ALL 关键字表示满足所有条件。使用ALL关键字时,只有满足内层查询语句返回的所有结果,才可以执行外层查询语句。例如,需要查询哪些同学能够获得一等奖学 金。首先必须从奖学金表中查询出各种奖学金要求的最低分。因为一等奖金要求的分数最高。只有当同学的成绩高于所有奖学金最低分时,这个同学才可能获得等奖 学金。ALL关键字也经常与比较运算符一起使用。
SELECT * FROM computer_stu
WHERE score>=ALL(SELECT score FROM scholarship);
2.6 合并查询结果
合 并查询结构是将多个SELECT语句的查询结果合并到一起。因为某种情况下,需要将几个SELECT语句查询出来的结果合并起来显示。例如,现在需要查询 公司甲和公司乙这两个公司所有员工的信息。这就需要从公司甲中查询出所有员工的信息,再从公司乙查询出所有员工的信息。然后将两次的查询结果合并到一起。 进行合并操作使用UNION和UNION ALL关键字。
使用UNION关键字时,数据库系统会将所有的查询结果合并到一起,然后去除相同的记录。而UNION ALl关键字则只是简单的合并到一起。
SELECT语句1
UNION | UNION ALL
SELECT语句2
UNION | UNION ALL...
SELECT语句n;
SELECT d_id FROM department;
SELECT d_id FROM employee;
SELECT d_id FROM department
UNION
SELECT d_id FROM employee;
SELECT d_id FROM department
UNION ALL
SELECT d_id FROM employee;
2. 7为表和字段取别名
在查询时,可以为表和字段取一个别名。这个别名可以代替其指定的表和字段。
2.7.1 为表取别名
当 表的名称特别长时,在查询中直接使用表名很不方便。这时可以为表取一个别名。用这个别名代替表的名称。例如,电力软件中的变压器的名称为 power_system_transform。如果要使用该表下面的字段id,但同时查询的其他表中也有id字段。这样就必须指明是哪个表下的id字 段,如power_system_transform.id。因为变压器表的表名太长,使用起来不是很方便。为了解决这个问题,可以将变压器表取一个别 名。如将power_system_transform取个别名为t,那么t就代表了变压器表。t.id就与 power_system_transform.id表示的意思相同了。
MySQL 中为表取别名的基本形式如下:
表名 表的别名
SELECT * FROM department [AS] D WHERE d.d_id=1001;
2.7.2 为字段取别名
当 查询数据时,MySQL会显示每个输出列的名词。默认的情况下,显示的列名是创建表是定义的列名。例如,department表的列名分别是d_id、 d_name、function和address。当查询department表时,就会相应显示这几个列名。有时为了显示结果更加直观,需要一个更加直 观的名字来表示这一列。如department_name可以很直接的知道是部门名称。这时就需要将d_name字段取别名为 deparment_name。
属性名 [AS] 别名
SELECT d_id AS department_id, d_name AS department_name FROM department;
SELECT d.d_id AS department_id, d.d_name AS department_name, d.function, d.address FROM department d WHERE d.d_id=1001;
2.8 使用正则表达式查询
正则表达式是用某种模式去匹配一类字符串的一个方式。例如,使用正则表达式可以查询出包含A、B、C其中任一字母的字符串。正则表达式的查询能力比通配字符的查询能力更强大,而且更加的灵活。正则表达式可以应用于非常复杂查询。
属性名 REGEXP '匹配方式'
正则表达式的模式字符
模式字符 含义
^ 匹配字符串开始的部分
$ 匹配字符串结尾的部分
. 代表字符串中的任意一个字符,包括回车和换行
[字符集合] 匹配'字符集合'中的任何一个字符
[^字符集合] 匹配除了'字符集合'中的以外的任何一个字符
S1|S2|S3 匹配S1、S2、S3中的任意一个字符串
* 代表多个该字符之前的字符,包括0和1个
+ 代表多个该符号之前的字符,包括1个
字符串{N} 字符串出现N次
字符串{M,N} 字符串出现至少M次,最多N次
2.8.1 查询以特定字符或字符串开头的记录
使用字符'^'可以匹配特定字符或字符串开头的记录。下面从info表name字段中查询以字母'L'开头的记录。
CREATE TABLE info(
id INT,
name VARCHAR(20)
) DEFAULT CHARSET=utf8;
INSERT INTO info VALUES(1, 'Aric');
INSERT INTO info VALUES(2, 'Eric');
INSERT INTO info VALUES(3, 'Jame');
INSERT INTO info VALUES(4, 'Jack');
INSERT INTO info VALUES(5, 'Lucy');
INSERT INTO info VALUES(6, 'Lily');
INSERT INTO info VALUES(7, 'Tom');
INSERT INTO info VALUES(8, 'aaa');
INSERT INTO info VALUES(9, 'dadaaa');
INSERT INTO info VALUES(10, '2323');
INSERT INTO info VALUES(11, 'bbdfec12');
INSERT INTO info VALUES(12, '212abc');
INSERT INTO info VALUES(17, 'werabc');
SELECT * FROM info WHERE name REGEXP '^L';
SELECT * FROM info WHERE name REGEXP '^aaa';
2.8.2 查询以特定字符或字符串结尾的记录
SELECT * FROM info WHERE name REGEXP 'c$';
# SELECT * FROM info WHERE name REGEXP 'aaa$';
2.8.3 用符号'.'来替代字符串任意一个字符
# SELECT * FROM info WHERE name REGEXP '^L..y$';
2.8.4 匹配指定字符串的任意一个
使用方括号([])可以将需要查询字符组成一个字符集。只要记录中包含方括号中的任意字符,该记录将会被查询出来。例如,通过"[abc]"可以查询包括a、b、c这三个字母中任何一个的记录。
SELECT * FROM info WHERE name REGEXP '[ceo]';
SELECT * FROM info WHERE name REGEXP '[0-9]';
2.8.5 匹配指定字符以外的字符
使用'[^字符集合]'可以匹配指定字符以外的字符。从info表字段中查询包含a到w字母和数字以外的字符的记录。
SELECT * FROM info WHERE name REGEXP '[^a-w0-9]';
2.8.6 匹配指定字符串
正则表达式可以匹配字符串。当表中的记录包含这个字符串时,就可以将该记录查询出来。如果指定多个字符串时,需要用符号'|'隔开。只要匹配这些字符串中的任意一个即可。
SELECT * FROM info WHERE name REGEXP 'ic';
SELECT * FROM info WHERE name REGEXP 'ic|ab|uc';
2.8.7 使用'*'和'+'来匹配多个字符
正则表达式中,'*'和'+'都可以匹配多个该符号之间的字符。但是,'+'至少表示一个字符,而'*'可以表示零个字符。
SELECT * FROM info WHERE name REGEXP 'a*c';
SELECT * FROM info WHERE name REGEXP 'a+c';
2.8.8 使用{M}或者{M,N}来指定字符串连续出现的次数
正则表达式中,'字符串{M}'表示字符串连续出现M次;'字符串{M,N}'表示字符串联连续出现至少M次,最多N次。例如,'ab{2}'表示字符串'ab'连续出现两次。'ab{2,4}'表示字符串'ab'连续出现至少两次,最多四次。
SELECT * FROM info WHERE name REGEXP 'a{3}';
SELECT * FROM info WHERE name REGEXP 'ab{1,3}';