学习参考文档:
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;
查看数据库服务器中的所有数据库:show databases;
在数据库服务器中创建数据库:create database databaseName;
选择数据库进行操作:use databasesName;
查看某个数据库中的表:show tables;
查看数据表的结构:describe tableName;
创建一个数据表,假设创建一个 person 表
create 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)
数据库主键,指的是一个列或多列的组合,其值能唯一地标识表中的每一行,通过它可强制表的实体完整性。主键主要是用与其他表的外键关联,以及本记录的修改与删除。
主键约束在表中定义一个主键来唯一确定表中每一行数据的标识符.(非空,唯一)
建表时添加主键约束
CREATE 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 个以上的字段组成主键,用这个主键包含的字段作为主键,这个组合在数据表中是唯一,且附加上了主键索引。
联合主键中任何一个字段都不可为空。
CREATE TABLE user (
id INT,
name VARCHAR(20),
password VARCHAR(20),
PRIMARY KEY(id, name)
);
(AUTO INCREMENT)
Auto-increment 会在新记录插入表中时生成一个唯一的数字。
CREATE TABLE user (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20)
);
(UNIQUE)
唯一约束保证在一个字段或者一组字段里的数据与表中其它行的数据相比是唯一的。(可为空,但不能重复)
主键约束(primary key)中包含了唯一约束
CREATE 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 约束强制字段始终包含值。这意味着,如果不向字段添加值,就无法插入新记录或者更新记录。
CREATE TABLE user (
id INT,
name VARCHAR(20) NOT NULL
);
ALTER TABLE [表名] modify [列名] varchar(20) null;
(DEFAULT)
DEFAULT 约束用于向列中插入默认值。
如果没有规定其他的值,那么会将默认值添加到所有的新记录。
CREATE TABLE user (
id INT,
name VARCHAR(20),
age INT DEFAULT 10
);
ALTER TABLE user modify age INT(4);
(FOREIGN KEY)
表的外键是另一表的主键, 外键可以有重复的值, 可以是空值。
CREATE TABLE classes (
id INT PRIMARY KEY,
name VARCHAR(20)
);
CREATE TABLE students (
id INT PRIMARY KEY,
name VARCHAR(20),
class_id INT,
FOREIGN KEY(class_id) REFERENCES classes(id)
);
class_id
的值必须来自于classes
中的id
字段值在数据库中,CHECK 约束是指约束表中某一个或者某些列中可接受的数据值或者数据格式。
CHECK 约束是用来指定某一个属性或多个属性可以满足的条件,可以定义列级约束或者表级约束
CREATE TABLE students (
id INT PRIMARY KEY,
NAME CHAR(10) NOT NULL,
SEX CHAR(2) CHECK(SEX IN ('男','女'))
);
SELECT 语句用于从表中选取数据。
SELECT 列名称1,列名称2,... FROM 表名称
查询表里的所有列:SELECT * FROM 表名称;
- 在表中,一个列可能会包含多个重复值,有时您也许希望仅仅列出不同(distinct)的值。
- DISTINCT 关键词用于返回唯一不同的值。
SELECT DISTINCT 列名称 FROM 表名称
WHERE 子句用于提取那些满足指定条件的记录,可将 WHERE 子句添加到 SELECT 语句。
SELECT 列名称 FROM 表名称 WHERE 列 运算符 值
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 关键字用于对结果集按照一个列或者多个列进行排序。
DESC
: 降序,从高到低
ASC
(默认): 升序,从低到高
例:
SELECT * 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 可以被用于强制 SELECT 语句返回指定的记录数。Limit 接受一个或两个数字参数。参数必须是一个整数常量。如果给定两个参数,第一个参数指定第一个返回记录行的偏移量,第二个参数指定返回记录行的最大数目。
SELECT s_no, c_no, degree FROM score ORDER BY degree DESC LIMIT 0, 1;
(AS)
通过使用 SQL,可以为表名称或列名称指定别名。
基本上,创建别名是为了让列名称的可读性更强。
列的 SQL 别名语法
SELECT column_name AS alias_name
FROM table_name;
表的 SQL 别名语法
SELECT column_name(s)
FROM table_name AS alias_name;
UNION 操作符用于合并两个或多个 SELECT 语句的结果集。
SELECT column_name(s) FROM table1
UNION
SELECT column_name(s) FROM table2;
默认地,UNION 操作符选取不同的值。如果允许重复的值,请使用 UNION ALL。
SELECT column_name(s) FROM table1
UNION ALL
SELECT column_name(s) FROM table2;
UNION 结果集中的列名总是等于 UNION 中第一个 SELECT 语句中的列名。
GROUP BY 语句用于结合合计函数,根据一个或多个列对结果集进行分组。
SELECT S_id,AVG(GRADE) FROM SC GROUP BY S_id;
SELECT c_no,AVG(sc_degree) FROM SCORE GROUP BY c_no;
- 在 SQL 中增加 HAVING 子句原因是,WHERE 关键字无法与聚合函数一起使用。
- HAVING 子句可以让我们筛选分组后的各组数据。
score
表中至少有 2 名学生选修,并以 3 开头的课程的平均分数:SELECT c_no, AVG(degree), COUNT(*) FROM score GROUP BY c_no
HAVING COUNT(c_no) >= 2 AND c_no LIKE '3%';
SELECT SCODE,COUNT(*) FROM S GROUP BY SCODE HAVING COUNT(*)>300;
查询所有的学生的姓名s_name, 班级c_no, 成绩sc_degree
SELECT s_name, c_no, sc_degree FROM student,score WHERE student.s_no = score.s_no;
查询所有学生的学号s_no,课程c_name,成绩sc_degree
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为成绩表
SELECT S.S#,SNAME FROM S,SC
WHERE S.S# = SC.S# AND C# ='C401001'’;
在SQL语言中,如果在一个SELECT语句的 WHERE子句中嵌入了另一个SELECT语句,则称这种查询为嵌套查询。
WHERE子句中的SELECT语句称为子查询,外部的查询称为父查询。
查询张华同学(学号为200401001)的那个班的女同学的基本信息。
SELECT * FROM S
WHERE CLASS=(SELECT CLASS FROM S WHERE S#='200401001')
AND SSEX='女';
查询班级是’95031’班学生每门课的平均分
select 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"还要高的学生信息)
SELECT * 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
SELECT * FROM student
WHERE YEAR(s_birthday) IN (SELECT YEAR(s_birthday) FROM student WHERE s_no IN('108','101'));
查询选修课程的同学人数多于 5 人的教师信息
SELECT * 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 操作符将来自不同查询的数据组合起来,形成一个具有综合信息的查询结果。
SELECT * 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为成绩表
SELECT S.S#,SNAME FROM S
WHERE S# = ANY (SELECT S# FROM SC WHERE C# ='C401001');
查询所有学习了数据结构课(课程号为C401001)的学生的学号和姓名。
SELECT S.S#,SNAME FROM S
WHERE EXISTS (SELECT * FROM SC WHERE SC.S# = S.S# AND C# ='C401001');
查询考试成绩大于计算机科学专业(专业代码S0401)所有学生课程成绩的学生的基本信息
SELECT 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 表中 不姓"王"的同学的记录
SELECT * FROM student WHERE s_name NOT LIKE '王%';
id | name |
---|---|
1 | 饭卡 |
2 | 建行卡 |
3 | 农行卡 |
4 | 工商卡 |
5 | 邮政卡 |
id | name | cardId |
---|---|---|
1 | 张三 | 1 |
2 | 李四 | 3 |
3 | 王五 | 6 |
INNER JOIN
INNER JOIN 关键字在表中存在至少一个匹配时返回行。
要查询这两张表中有关系的数据,可以使用 INNER JOIN
( 内连接 ) 将它们连接在一起。
SELECT * FROM person INNER JOIN card on person.cardId = card.id;
查询结果:
id | name | cardId | id | name |
---|---|---|---|---|
1 | 张三 | 1 | 1 | 饭卡 |
2 | 李四 | 3 | 3 | 农行卡 |
left join
/left outer join
LEFT JOIN 关键字从左表(table1)返回所有的行,即使右表(table2)中没有匹配。如果右表中没有匹配,则结果为 NULL。
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
。right join
/right outer join
RIGHT JOIN 关键字从右表(table2)返回所有的行,即使左表(table1)中没有匹配。如果左表中没有匹配,则结果为 NULL。
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
。full join
/full outer join
FULL OUTER JOIN 关键字只要左表(table1)和右表(table2)其中一个表中存在匹配,则返回行.
FULL OUTER JOIN 关键字结合了 LEFT JOIN 和 RIGHT JOIN 的结果。
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 将两张表合并在一起。
SELECT * 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(*)
: 计算元组的个数
SELECT COUNT(*) FROM student WHERE class = '1';
MAX(列名)
:函数返回指定列的最大值。
MIN(列名)
:返回一列中的最小值。NULL 值不包括在计算中。
AVG(列名)
:返回数值列的平均值。NULL 值不包括在计算中。
计算所有学生所学课程的最高分数、最低分数和平均分数。
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 函数返回当前的日期和时间。
查询student 中每个学生的姓名和年龄(当前时间 - 出生年份)
SELECT s_name, YEAR(NOW()) - YEAR(s_birthday) AS age FROM student;
MAX()
:MAX 函数返回一列中的最大值。NULL 值不包括在计算中。
MIN()
:MIN 函数返回一列中的最小值。NULL 值不包括在计算中。
查询student中最大和最小的 s_birthday的值
SELECT MAX(s_birthday),MIN(s_birthday) FROM student;
SUM()
:SUM 函数返回数值列的总数(总额)。
SELECT SUM(column_name) FROM table_name
COUNT DISTINCT(列名)
:计算某一列中不同值的个数