学习参考文档:
https://www.w3school.com.cn/sql/index.asp
https://www.runoob.com/sql/sql-tutorial.html
学习参考视频:https://www.bilibili.com/video/av39807944
学习MySQL的同时做了些笔记,分享给大家,与大家一同学习进步~
SQL 语句对大小写不敏感。
数据库服务的启动、登录、退出
启动服务:net start mysql
登入:mysql -u root -p
,然后输密码,或者mysql -u root -p密码
退出数据库服务器:exit;
常用 sql 语句
查看数据库服务器中的所有数据库:show databases;
在数据库服务器中创建数据库:create database databaseName;
选择数据库进行操作:use databasesName;
查看某个数据库中的表:show tables;
查看数据表的结构:describe tableName;
创建一个数据表,假设创建一个 person 表1
2
3
4create TABLE person(
name VARCHAR(20),
sex CHAR(1),
brith DATE);
表中数据的增删改查
往表中插入数据:INSERT INTO 表名称 VALUES ('值1', '值2',....);
INSERT INTO table_name ('列1', '列2',...) VALUES ('值1', '值2',....);
从表中删除数据:DELETE FROM tableName WHERE 列名称 = '值';
修改数据:UPDATE tableName SET 列名称 = '新值' WHERE 列名称 = '某值';
查询某张表的数据:select * from tableName;
建表约束
主键约束(PRIMARY KEY)
建表时创建约束
数据库主键,指的是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性。主键主要是用与其他表的外键关联,以及本记录的修改与删除。
主键约束在表中定义一个主键来唯一确定表中每一行数据的标识符.(非空,唯一)
建表时添加主键约束
1
2
3
4CREATE TABLE user (
id INT PRIMARY KEY,
name VARCHAR(20)
);表已建好,添加主键约束
ALTER TABLE user ADD PRIMARY KEY(id);
ALTER TABLE user MODIFY id INT PRIMARY KEY;
删除主键
ALTER TABLE user drop PRIMARY KEY;
联合主键
联合主键就是用 2 个或 2 个以上的字段组成主键,用这个主键包含的字段作为主键,这个组合在数据表中是唯一,且附加上了主键索引。
联合主键中任何一个字段都不可为空。
1 | CREATE TABLE user ( |
自增约束(AUTO INCREMENT)
Auto-increment 会在新记录插入表中时生成一个唯一的数字。
- 我们通常希望在每次插入新记录时,自动地创建主键字段的值。
- 我们可以在表中创建一个 auto-increment 字段。
1
2
3
4CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20)
);
唯一约束(UNIQUE)
唯一约束保证在一个字段或者一组字段里的数据与表中其它行的数据相比是唯一的。(可为空,但不能重复)
主键约束(primary key)中包含了唯一约束
建表时添加唯一约束
1
2
3
4
5CREATE TABLE user (
id INT,
name VARCHAR(20),
UNIQUE(name)
);表已建好,添加唯一约束
ALTER TABLE user ADD UNIQUE(name);
ALTER TABLE user MODIFY name VARCHAR(20) UNIQUE;
非空约束(NOT NULL)
NOT NULL 约束强制列不接受 NULL 值。
NOT NULL 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。
建表时添加非空约束
1
2
3
4CREATE TABLE user (
id INT,
name VARCHAR(20) NOT NULL
);取消非空约束
ALTER TABLE [表名] modify [列名] varchar(20) null;
默认约束(DEFAULT)
DEFAULT 约束用于向列中插入默认值。
如果没有规定其他的值,那么会将默认值添加到所有的新记录。
建表时添加默认约束
1
2
3
4
5CREATE TABLE user (
id INT,
name VARCHAR(20),
age INT DEFAULT 10
);取消默认约束
ALTER TABLE user modify age INT(4);
外键约束(FOREIGN KEY)
表的外键是另一表的主键, 外键可以有重复的值, 可以是空值。
1 | CREATE TABLE classes ( |
class_id
的值必须来自于classes
中的id
字段值
CHECK 约束
在数据库中,CHECK 约束是指约束表中某一个或者某些列中可接受的数据值或者数据格式。
CHECK 约束是用来指定某一个属性或多个属性可以满足的条件,可以定义列级约束或者表级约束
1 | CREATE TABLE students ( |
数据查询
SELECT 语句
SELECT 语句用于从表中选取数据。
SELECT 列名称1,列名称2,... FROM 表名称
查询表里的所有列:SELECT * FROM 表名称;
SELECT DISTINCT 语句
- 在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。
- DISTINCT 关键词用于返回唯一不同的值。
SELECT DISTINCT 列名称 FROM 表名称
WHERE 子句
WHERE 子句用于提取那些满足指定条件的记录,可将 WHERE 子句添加到 SELECT 语句。
SELECT 列名称 FROM 表名称 WHERE 列 运算符 值
运算符
AND
、OR
:- 如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。
- 如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。
is null
:空值判断BETWEEN
:查询区间IN
: 查询规定中的多个值NOT IN
: 某列的值不属于集合成员中的任何一个成员like
:模糊查询
SQL 通配符:https://www.runoob.com/sql/sql-wildcards.html
更多例子:https://www.runoob.com/sql/sql-where.html
ORDER BY 子句
ORDER BY 关键字用于对结果集按照一个列或者多个列进行排序。
DESC
: 降序,从高到低ASC
(默认): 升序,从低到高
例:1
2
3
4
5
6
7SELECT * FROM student ORDER BY class DESC;
SELECT * FROM student ORDER BY class ASC;
SELECT * FROM student ORDER BY class;
SELECT * FROM score ORDER BY c_no ASC, degree DESC;
以 c_no 升序、degree 降序查询 score 表的所有行
LIMIT 关键字
Limit 可以被用于强制 SELECT 语句返回指定的记录数。Limit 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。
- LIMIT r, n: 表示从第 r 行开始,查询 n 条数据:
1
SELECT s_no, c_no, degree FROM score ORDER BY degree DESC LIMIT 0, 1;
别名(AS)
通过使用 SQL,可以为表名称或列名称指定别名。
基本上,创建别名是为了让列名称的可读性更强。
列的 SQL 别名语法
1
2SELECT column_name AS alias_name
FROM table_name;表的 SQL 别名语法
1
2SELECT column_name(s)
FROM table_name AS alias_name;
UNION 操作符
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
1 | SELECT column_name(s) FROM table1 |
默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
1
2
3SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
分组查询
GROUP BY 子句
GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组。
计算各个同学的平均分,SC为成绩表:
1
SELECT S_id,AVG(GRADE) FROM SC GROUP BY S_id;
查询每门课的平均成绩
1
SELECT c_no,AVG(sc_degree) FROM SCORE GROUP BY c_no;
HAVING 子句
- 在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。
- HAVING 子句可以让我们筛选分组后的各组数据。
查询
score
表中至少有 2 名学生选修,并以 3 开头的课程的平均分数:1
2SELECT c_no, AVG(degree), COUNT(*) FROM score GROUP BY c_no
HAVING COUNT(c_no) >= 2 AND c_no LIKE '3%';查询学生总数超过 300 人的专业及其具体的总人数
1
SELECT SCODE,COUNT(*) FROM S GROUP BY SCODE HAVING COUNT(*)>300;
多表查询
多表连接查询
查询所有的学生的姓名s_name, 班级c_no, 成绩sc_degree
1
SELECT s_name, c_no, sc_degree FROM student,score WHERE student.s_no = score.s_no;
查询所有学生的学号s_no,课程c_name,成绩sc_degree
1
SELECT student.s_no, c_name, sc_degree FROM student, course,score WHERE student.s_no = score.s_no AND score.c_no = course.c_no ;
- 查询所有学习了数据结构课(课程号为C401001)的学生的学号(S#)和姓名(SNAME),S为学生表,SC为成绩表
1
2SELECT S.S#,SNAME FROM S,SC
WHERE S.S# = SC.S# AND C# ='C401001'’;
嵌套查询
在SQL语言中,如果在一个SELECT语句的 WHERE子句中嵌入了另一个SELECT语句,则称这种查询为嵌套查询。
WHERE子句中的SELECT语句称为子查询,外部的查询称为父查询。
查询张华同学(学号为200401001)的那个班的女同学的基本信息。
1
2
3SELECT * FROM S
WHERE CLASS=(SELECT CLASS FROM S WHERE S#='200401001')
AND SSEX='女';查询班级是’95031’班学生每门课的平均分
1
2
3select c_no,AVG(sc_degree) from score
WHERE s_no IN (select s_no from student where s_class = '95031')
GROUP BY c_no;查询选修”3-105”课程的成绩高于’109’号同学’3-105’成绩 的所有同学的记录(在大家都在选修3-105的背景下 查询 所有 分数 比 学号为”109”还要高的学生信息)
1
2SELECT * FROM student AS s, score AS sc
WHERE sc.c_no = '3-105' AND sc.sc_degree > (SELECT sc_degree FROM score WHERE s_no = '109' AND c_no = '3-105') AND s.s_no = sc.s_no;查询所有学号为108、101的同学同年出生的所有学生的s_no,s_name和s_birthday
1
2SELECT * FROM student
WHERE YEAR(s_birthday) IN (SELECT YEAR(s_birthday) FROM student WHERE s_no IN('108','101'));查询选修课程的同学人数多于 5 人的教师信息
1
2SELECT * FROM teacher
WHERE t_no IN(SELECT t_no FROM course WHERE c_no IN (SELECT c_no FROM score GROUP BY c_no HAVING COUNT(s_no) > 5));先找出选修课程的同学人数多于 5 人的课程,再找出课程对应的老师,再找老师信息
合并查询
合并查询就是使用UNION 操作符将来自不同查询的数据组合起来,形成一个具有综合信息的查询结果。
- 查询’计算机系’与’电子工程系’不同职称的教师的name和prof(职称)
1
2
3SELECT * FROM teacher WHERE t_depart = '计算机系' AND prof NOT IN (SELECT prof FROM teacher WHERE t_depart = '电子工程系')
UNION
SELECT * FROM teacher WHERE t_depart = '电子工程系' AND prof NOT IN (SELECT prof FROM teacher WHERE t_depart = '计算机系');
谓词演算查询
操作符 | 说明 |
---|---|
between A and B | 某列的数值区间是[A,B] |
not between A and B | 某列的数值区间在[A,B]外 |
like | 两个字符串的部分字符相等,其余可以任意 |
in | 某列的某个值属于集合成员中的一个成员 |
not in | 某列的值不属于集合成员中的任何一个成员 |
any | 某列的值满足一个条件即可 |
some | 满足集合中的某些值 |
all | 某列的值满足子查询中所有值的记录 |
exists | 总存在一个值满足条件 |
not exists | 不存在任何值满足条件 |
查询所有学习了数据结构课(课程号为C401001)的学生的学号和姓名。S为学生表,SC为成绩表
1
2SELECT S.S#,SNAME FROM S
WHERE S# = ANY (SELECT S# FROM SC WHERE C# ='C401001');查询所有学习了数据结构课(课程号为C401001)的学生的学号和姓名。
1
2SELECT S.S#,SNAME FROM S
WHERE EXISTS (SELECT * FROM SC WHERE SC.S# = S.S# AND C# ='C401001');查询考试成绩大于计算机科学专业(专业代码S0401)所有学生课程成绩的学生的基本信息
1
2
3SELECT S.* FROM S,SC
WHERE S.S#=SC.S#
AND GRADE > ALL (SELECT GRADE FROM S,SC WHERE S.S#=SC.S# AND SCODE='S0401');查询student 表中 不姓”王”的同学的记录
1
SELECT * FROM student WHERE s_name NOT LIKE '王%';
连接查询
- card表
id | name |
---|---|
1 | 饭卡 |
2 | 建行卡 |
3 | 农行卡 |
4 | 工商卡 |
5 | 邮政卡 |
- person表
id | name | cardId |
---|---|---|
1 | 张三 | 1 |
2 | 李四 | 3 |
3 | 王五 | 6 |
内连接:INNER JOIN
INNER JOIN 关键字在表中存在至少一个匹配时返回行。
要查询这两张表中有关系的数据,可以使用
INNER JOIN
( 内连接 ) 将它们连接在一起。1
SELECT * FROM person INNER JOIN card on person.cardId = card.id;
查询结果:
id | name | cardId | id | name |
---|---|---|---|---|
1 | 张三 | 1 | 1 | 饭卡 |
2 | 李四 | 3 | 3 | 农行卡 |
- INNER JOIN: 表示为内连接,将两张表拼接在一起。(求表的交集)
- on: 表示要执行某个条件。
- 内联查询,其实就是两张表中的数据,通过某个字段相对,查询出相关记录数据。
外连接
左连接:left join
/left outer join
LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。
1 | SELECT * FROM person LEFT JOIN card on person.cardId = card.id; |
查询结果:
id | name | cardId | id | name |
---|---|---|---|---|
1 | 张三 | 1 | 1 | 饭卡 |
2 | 李四 | 3 | 3 | 农行卡 |
3 | 王五 | 6 | NULL | NULL |
- 完整显示左边的表 (
person
) ,右边的表如果符合条件就显示,不符合则补NULL
。 - LEFT JOIN 也叫做 LEFT OUTER JOIN,用这两种方式的查询结果是一样的。
右连接:right join
/right outer join
RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配。如果左表中没有匹配,则结果为 NULL。
1 | SELECT * FROM person RIGHT JOIN card on person.cardId = card.id; |
查询结果:
id | name | cardId | id | name |
---|---|---|---|---|
1 | 张三 | 1 | 1 | 饭卡 |
2 | 李四 | 3 | 3 | 农行卡 |
NULL | NULL | NULL | 2 | 建行卡 |
NULL | NULL | NULL | 4 | 工商卡 |
NULL | NULL | NULL | 5 | 邮政卡 |
- 完整显示右边的表 (
card
) ,左边的表如果符合条件就显示,不符合则补NULL
。 - RIGHT JOIN 也叫做 RIGHT OUTER JOIN,用这两种方式的查询结果是一样的。
完全外连接:full join
/full outer join
FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行.
FULL OUTER JOIN 关键字结合了 LEFT JOIN 和 RIGHT JOIN 的结果。
1 | SELECT * FROM person FULL JOIN card on person.cardId = card.id; |
查询结果:ERROR 1054 (42S22): Unknown column 'person.cardId' in 'on clause'
MySQL 不支持full join
MySQL全连接语法,使用 UNION 将两张表合并在一起。
1
2
3SELECT * FROM person LEFT JOIN card on person.cardId = card.id
UNION
SELECT * FROM person RIGHT JOIN card on person.cardId = card.id;查询结果:
id | name | cardId | id | name |
---|---|---|---|---|
1 | 张三 | 1 | 1 | 饭卡 |
2 | 李四 | 3 | 3 | 农行卡 |
3 | 王五 | 6 | NULL | NULL |
NULL | NULL | NULL | 2 | 建行卡 |
NULL | NULL | NULL | 4 | 工商卡 |
NULL | NULL | NULL | 5 | 邮政卡 |
- 完整显示两张表的全部数据。
聚合函数
能够根据查询结果的记录集或根据查询结果的记录集中某列值的特点返回一个汇总信息的函数。
COUNT(*)
: 计算元组的个数1
SELECT COUNT(*) FROM student WHERE class = '1';
MAX(列名)
:函数返回指定列的最大值。MIN(列名)
:返回一列中的最小值。NULL 值不包括在计算中。AVG(列名)
:返回数值列的平均值。NULL 值不包括在计算中。1
2
3
4
5计算所有学生所学课程的最高分数、最低分数和平均分数。
SELECT MAX(GRADE),MIN(GRADE),AVG(GRADE) FROM score;
查询 score 表中的最高分的学生学号和课程编号(子查询或排序查询)。
SELECT s_no, c_no FROM score WHERE degree = (SELECT MAX(degree) FROM score);NOW()
:NOW 函数返回当前的日期和时间。1
2查询student 中每个学生的姓名和年龄(当前时间 - 出生年份)
SELECT s_name, YEAR(NOW()) - YEAR(s_birthday) AS age FROM student;MAX()
:MAX 函数返回一列中的最大值。NULL 值不包括在计算中。MIN()
:MIN 函数返回一列中的最小值。NULL 值不包括在计算中。1
2查询student中最大和最小的 s_birthday的值
SELECT MAX(s_birthday),MIN(s_birthday) FROM student;SUM()
:SUM 函数返回数值列的总数(总额)。1
SELECT SUM(column_name) FROM table_name
COUNT DISTINCT(列名)
:计算某一列中不同值的个数
- 本文作者: Niccce
- 本文链接: https://niccce.github.io/2020/03/01/about-MySQL/
- 版权声明: 本博客所有文章除特别声明外,均采用 Apache License 2.0 许可协议。转载请注明出处!