数据库概述
为什么学习数据库:
- 实现数据持久化到本地;
- 使用完整的管理系统统一管理,可以实现结构化查询,方便管理
数据库(DataBase) 为了方便数据的存储和管理,它将数据按照特定的 规则存储在磁盘上,就是一个存储数据的仓库。通过数据库管理系统,可 以有效的组织和管理存储在数据库中的数据。
数据库的相关概念:
- DB:数据库(DataBase) 存储数据的容器,它保存了一系列有组织的数据。
- DBMS:数据库管理系统(DataBase Management System) 又称为数据库软件或数据库产品,用于创建或管理DB
- SQL:结构化查询语言(Structure Query Language)
用于和数据库通信的语言,不是某个数据库软件特有的,而是几乎所有的 主流数据 库软件通用的语言
数据库根据不同的存储类型可以分为关系型数据库和非关系型数据库
关系型数据库: 关系型数据库管理系统称为RDBMS,R指Relation
- Oracle:功能强大,收费
- MySQL 快捷、可靠 开源、免费
- SQL Server(微软): 只能安装在Windows操作系统
- DB2 (IBM):适合处理海量数据,收费
非关系型数据库: - MongdoDB
- Redis
MySQL数据库
MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目 前属于 Oracle旗下产品。MySQL 流行的关系型数据库管理系统。
- MySql是一种关系数据库管理系统。
- MySql软件是一种开放源码软件,你可以修改源码来开发自己的 Mysql 系统。
- MySql数据库服务器具有快速、可靠和易于使用的特点
- MySql使用标准的sql语言,并且支持多种操作系统,支持多种语言
- mysql商业版与社区版
- MySQL商业版是由MySQL AB公司负责开发与维护,需要付费才能使用
- MySQL社区版是由分散在世界各地的MySQL开发者、爱好者一起开发与维 护,可以免费使用
安装:
查看
语法
SQL–DDL
SOL
结构化查询语言(Structured Query Language)简称SQL,是一种特殊 目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统.
SQL优点:不是某个特定数据库供应商专有的语是言,几乎所有DBMS都支持SQL 简单易学 实际上强有力的语言,灵活使用可以进行非常复杂和高级的数据库操作
DDL
数据(结构)定义语言DDL(Data Definition Language),是用于创 建和修改数据库表结构的语言
常用语句:
- create 创建 可以创建数据库、表
- alter 修改
- drop 删除
- rename(ddl不能修改数据库名)
#Select * from user;
-- 创建数据库/ 如果此库不存在,则创建改数据库
CREATE DATABASE IF NOT EXISTS school_db;
-- utf8编码的数据库
CREATE DATABASE IF NOT EXISTS school_db1 CHARSET utf8;
-- 修改字符集
ALTER DATABASE school_db CHARSET gbk;
-- 删除数据库
DROP DATABASE school_db1;
-- mysql不能修改数据库名称
数据库存储数据的特点:
- 将数据放到表中,表再放到库中
- 一个数据库中可以有多个表,每个表都有一个名字,用来标识自己。表名具有 唯一性。
- 表具有一些特性,这些特性定义了数据在表中如何存储,类似Java中“类”的设计。
- 表由列组成,我们也称列为字段。所有表都是由一个或多个列组成的,每一列 类似java中的”属性”
- 表中的数据是按行存储的,每一行类似于Java中的“对象”。
数据库表的基本概念
- 数据表:是数据存储的最常见和最简单的形式,是构成关系型数据库的基本元素。表的最简单形式是由行和列组成,分别都包含着数据。每个表都有一个表头和表体,表头定义表名和列名 .表中的行被看作是文件中的记录,表中的列被看作是这些记录的字段。
- 记录,也就是行。**在关系型数据库的表里,一行数据是指一条完 整的记录。**也就是java中的对象
- 字段,也就是列。**字段是表里的一列,用于保存每条记录的特定信息。**也就是java中的属性
表、设计表
对于具体的某一个表,在创建之前,需要确定表的下列特征:
- 表名(表信息)
- 表中的字段
- 字段的数据类型和长度
- 哪些约束
/*
约束:
PRIMARY KEY 主键约束 不能为空,不能重复,一个表只能有一个主键约束
AUTO_INCREMENT 主键自增(选填)
NOT NULL 不能为空
UNIQUE 唯一,不能重复
DEFAULT'男' 默认为'男'
CHECK(height>100.0)
*/
CREATE TABLE t_student(
num INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(4) NOT NULL, -- 名字最多有4个字符长
sex CHAR(1) DEFAULT'男', -- 性别
birthday DATE NOT NULL,-- 日期 ,日为最小单位
height FLOAT(4,1) CHECK(height>100.0),
phone CHAR(11) NOT NULL UNIQUE,
register_time DATETIME -- 秒为最小单位 最后一位不需要加逗号`num``name`
-- 选中表,然后运行到库里面
)
数据类型:
char(n) 长度为n的定长字符串
varchar(n) 最大长度为n的可变长字符串
date 日期, 包含年月日
datetime 年月日 时分秒
(不常用)
主键: 在一张表中代表唯一的一条记录,不能为空,不能重复
约束:
/*
约束:
PRIMARY KEY 主键约束 不能为空,不能重复,一个表只能有一个主键约束
AUTO_INCREMENT 主键自增(选填)
NOT NULL 不能为空
UNIQUE 唯一,不能重复
DEFAULT'男' 默认为'男'
CHECK(height>100.0)
COMMENT 默认值
*/
CREATE TABLE t_student(
num INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(4) NOT NULL, -- 名字最多有4个字符长
sex CHAR(1) DEFAULT'男', -- 性别
birthday DATE NOT NULL,-- 日期 ,日为最小单位
height FLOAT(4,1) CHECK(height>100.0),
phone CHAR(11) NOT NULL UNIQUE,
register_time DATETIME -- 秒为最小单位 最后一位不需要加逗号`num``name`
-- 选中表,然后运行到库里面
)
-- 修改表名字
RENAME TABLE student TO t_student;
-- 复制表 例如对某张表进行备份操作
CREATE TABLE stu LIKE t_student;
-- 添加/删除主键约束
ALTER table55
ALTER TABLE t_student DROP PRIMARY KEY
-- 设置主键自增/删除主键自增
ALTER TABLE t_student MODIFY num INT AUTO_INCREMENT;
ALTER TABLE t_student MODIFY num INT;
-- 设置列表不能为空/可以为空
ALTER TABLE t_student MODIFY NAME VARCHAR(4) NOT NULL;
ALTER TABLE t_student MODIFY NAME VARCHAR(4) NULL;
-- 添加检查约束,删除检查约束
ALTER TABLE t_student ADD CONSTRAINT check_height CHECK(height>100);
ALTER TABLE t_student DROP CHECK check_height;
-- 添加唯一约束,检查唯一约束
ALTER TABLE t_student ADD CONSTRAINT uni_phone UNIQUE(phone);
ALTER TABLE t_student DROP INDEX uni_phone;
-- 修改表结构 添加列、删除列,修改列的名称、类型
ALTER TABLE t_student ADD weight FLOAT(5,2)
ALTER TABLE t_student ADD weight FLOAT(5,2) AFTER height
ALTER TABLE t_student DROP weight
-- 将phone 变成CHAR型的mobile,长度为11
ALTER TABLE t_student CHANGE phone mobile CHAR(11)
-- 将mobile 修改成VARCHAR型
ALTER TABLE t_student MODIFY mobile VARCHAR(11)
SQL–DML
数据操纵语言DML(Data Manipulation Language)
-- DML 数据操作语言
-- insert(插入数据),delete(删除数据),update(修改数据)
-- now() sql底层方法,获取数据库所在系统的当前时间
INSERT INTO t_student(NAME,sex,birthday,height,weight,mobile,register_time)
VALUES('张三','男','2000-1-1',185.0,150,'13333333333',NOW())
INSERT INTO t_student SET NAME='李四',sex='女',birthday='2001-5-5',height=170.0,weight=100.0,
mobile='13333333332',register_time=NOW()
INSERT INTO t_student(NAME,sex,birthday,height,weight,mobile,register_time)
VALUES('马振强','男','2000-1-2',185.0,150,'13333333334',NOW()),
('王五','男','2000-1-3',185.0,150,'13333333335',NOW())
-- 复制表结构
CREATE TABLE stu LIKE t_student
-- 复制表数据
INSERT INTO stu (NAME,sex,birthday,height,weight,mobile,register_time)
SELECT NAME,sex,birthday,height,weight,mobile,register_time FROM t_student
-- 修改语句
UPDATE t_student SET NAME='张三'
UPDATE t_student SET NAME='王五',sex='男' WHERE num = 1 -- 注意条件
-- 删除语句
DELETE FROM t_student WHERE num = 1
-- 查询语句 DQL 使用频率最高的语句
-- select 查询列表(结果) from 表名;
-- select 结果 from 表名 where 条件 排序 分组
-- 多表 关联查询
-- 查询结果进行处理
SELECT NAME FROM t_student
SELECT height+5,NAME FROM t_student
SELECT VERSION()
SELECT CHAR_LENGTH(mobile) FROM t_student
-- * 所有列
SELECT * FROM t_student
-- 查询特定列(建议使用的)
SELECT num,NAME FROM t_student
-- 去除重复数据,针对查询出来的结果(num也要重复)
SELECT DISTINCT * FROM t_student
SELECT DISTINCT NAME FROM t_student
SQL–DQL
DQL(Data Query Language)数据查询语言查询是使用频率最高的一个操作, 可以从一个表中查询数据,也可以从多个表中查询数据
-- 查询语句 DQL 使用频率最高的语句
-- select 查询列表(结果) from 表名;
-- select 结果 from 表名 where 条件 排序 分组
-- 多表 关联查询
-- 查询结果进行处理
SELECT NAME FROM t_student
SELECT height+5,NAME FROM t_student
SELECT VERSION()
SELECT CHAR_LENGTH(mobile) FROM t_student
-- * 所有列
SELECT * FROM t_student
-- 查询特定列(建议使用的)
SELECT num,NAME FROM t_student
-- 去除重复数据,针对查询出来的结果(num也要重复)
SELECT DISTINCT * FROM t_student
SELECT DISTINCT NAME FROM t_student
/*
字符函数:
length():获取参数值的字节个数
char_length()获取参数值的字符个数
concat(str1,str2,.....):拼接字符串
upper()/lower():将字符串变成大写/小写
substring(str,pos,length):截取字符串 位置从1开始
instr(str,指定字符):返回子串第一次出现的索引,如果找不到返回0
trim(str):去掉字符串前后的空格或子串,trim(指定子串 from 字符串)
lpad(str,length,填充字符):用指定的字符实现左填充将str填充为指定长度
rpad(str,length,填充字符):用指定的字符实现右填充将str填充为指定长度
replace(str,old,new):替换,替换所有的子串
*/
-- 字符函数
-- length(列名)字节为单位 1中文3字节
SELECT num, LENGTH(NAME),sex FROM t_student
-- char_length(列名) 字符为单位,1个字符1单位
SELECT num, CHAR_LENGTH(NAME),sex FROM t_student
-- concat(str1,str2...)连接多个字符串 as 定义别名
SELECT CONCAT(NAME,':',sex)AS NAME FROM t_student
-- upper(列) 转大写 lower(列) 转小写
SELECT UPPER(NAME) FROM t_student
SELECT LOWER(NAME) FROM t_student
-- substring(str,开始位置(1开始而非0),截取的长度)
SELECT SUBSTRING(NAME,1,2)FROM t_student
-- instr(str,指定的字符)
SELECT INSTR(NAME,'三') FROM t_student
-- trim(列) 去掉前后的空格
SELECT CHAR_LENGTH(TRIM(NAME)) FROM t_student -- 空格也占一个字符长度
-- trim(子串,from 列) 去掉前后的子串
SELECT TRIM('张'FROM NAME) FROM t_student
-- lpad(列,指定最终长度,填充的子串) 左填充
SELECT LPAD(NAME,5,'c') FROM t_student
-- rpad(列,指定最终长度,填充的子串) 右填充
SELECT RPAD(NAME,5,'c') FROM t_student
-- replace(列,old,new) 更换
SELECT REPLACE(NAME,'三','四') FROM t_student
/*
逻辑处理:
case when 条件 then 结果1 else 结果2 end; 可以有多个when
ifnull(被检测值,默认值)函数检测是否为null,如果为null,则返回指定的值,否则返回原 本的值
if函数:if else的效果 if(条件,结果1,结果2)
*/
-- case when 条件 then 结果1 else 结果2 end; 可以有多个when
SELECT
num,
NAME,
(CASE WHEN height>=175 THEN'高个' ELSE'低个' END)height
FROM t_student
-- 还可以有多个when
SELECT
num,
NAME,
(CASE WHEN height>=175 THEN'高个'
WHEN height>=170 AND height<=175 THEN'中个'
ELSE '低个' END) height
FROM t_student
-- ifnull(列,默认值)
SELECT IFNULL(height,'暂未登记') FROM t_student
-- if(条件,成立,不成立)
SELECT IF(height>170,'高','低')height FROM t_student
/*
数学函数:
round(数值):四舍五入
ceil(数值):向上取整,返回>=该参数的最小整数
floor(数值):向下取整,返回<=该参数的最大整数
truncate(数值,保留小数的位数):截断,小数点后截断到几位
mod(被除数,除数):取余,被除数为正,则为正;被除数为负,则为负
rand():获取随机数,返回0-1之间的小数
*/
SELECT ROUND(3.4);
/*
日期函数:
now():返回当前系统日期+时间
curdate():返回当前系统日期,不包含时间
curtime():返回当前时间,不包含日期
可以获取指定的部分,年、月、日、小时、分钟、秒
YEAR(日期),MONTH(日期),DAY(日期) ,HOUR(日期) ,MINUTE(日期) SECOND(日期)
str_to_date:将日期格式的字符转换成指定格式的日期
date_format:将日期转换成字符串
datediff(big,small):返回两个日期相差的天数
*/
-- now():返回当前系统日期+时间
SELECT num,NAME,NOW() FROM t_student
-- curdate 获得年月日
SELECT num,NAME,CURDATE() FROM t_student
-- curtime 获得时分秒
SELECT num,NAME,CURTIME() FROM t_student
-- 获取已存入日期的年
SELECT num,NAME,YEAR(register_time)FROM t_student
-- 获取已存入日期的月
SELECT num,NAME,MONTH(register_time)FROM t_student
-- 获取已存入日期的日
SELECT num,NAME,DAY(register_time)FROM t_student
-- 字符串转为date类型
SELECT STR_TO_DATE('2021-7-6','%Y-%M-%d')
SELECT COUNT(*),DATE_FORMAT(birthday,'%Y-%m-%d')birth FROM t_student GROUP BY birth
/*
数学函数:
round(数值):四舍五入
ceil(数值):向上取整,返回>=该参数的最小整数
floor(数值):向下取整,返回<=该参数的最大整数
truncate(数值,保留小数的位数):截断,小数点后截断到几位
mod(被除数,除数):取余,被除数为正,则为正;被除数为负,则为负
rand():获取随机数,返回0-1之间的小数
*/
SELECT ROUND(3.4);
/*
日期函数:
now():返回当前系统日期+时间
curdate():返回当前系统日期,不包含时间
curtime():返回当前时间,不包含日期
可以获取指定的部分,年、月、日、小时、分钟、秒
YEAR(日期),MONTH(日期),DAY(日期) ,HOUR(日期) ,MINUTE(日期) SECOND(日期)
str_to_date:将日期格式的字符转换成指定格式的日期
date_format:将日期转换成字符串
datediff(big,small):返回两个日期相差的天数
*/
-- now():返回当前系统日期+时间
SELECT num,NAME,NOW() FROM t_student
-- curdate 获得年月日
SELECT num,NAME,CURDATE() FROM t_student
-- curtime 获得时分秒
SELECT num,NAME,CURTIME() FROM t_student
-- 获取已存入日期的年
SELECT num,NAME,YEAR(register_time)FROM t_student
-- 获取已存入日期的月
SELECT num,NAME,MONTH(register_time)FROM t_student
-- 获取已存入日期的日
SELECT num,NAME,DAY(register_time)FROM t_student
-- 字符串转为date类型
SELECT STR_TO_DATE('2021-7-6','%Y-%M-%d')
SELECT COUNT(*),DATE_FORMAT(birthday,'%Y-%m-%d')birth FROM t_student GROUP BY birth
/*
分组函数:功能:用作统计使用,又称为聚合函数或统计函数或组函数
分类:sum 求和、avg 平均值、max 最大值、min 最小值、count 计数 (非空)
1.sum,avg一般用于处理数值型max,min,count可以处理任何类型
2.以上分组函数都忽略null值
3.count函数的一般使用count(*)用作统计行数
4.和分组函数一同查询的字段要求是group by后的字段
*/
-- sum(列 数值),avg(列 数值),max(列 数值),min(列 数值),
-- 统计所有
SELECT SUM(weight) FROM t_student
-- 分组统计 sex 分组
SELECT SUM(weight),sex FROM t_student GROUP BY sex
-- 平均值
SELECT AVG(weight) FROM t_student
-- 最大/小值
SELECT MAX(weight) FROM t_student
SELECT MIN(weight) FROM t_student
-- 统计数量 (*/主键/指定列)
SELECT COUNT(height) FROM t_student
SELECT COUNT(num) FROM t_student
/*
条件查询:
使用WHERE 子句,将不满足条件的行过滤掉,WHERE 子句紧随 FROM 子句
语法:select <结果> from <表名> where <条件>
比较:
=, != 或<>, >, <, >=, <=
逻辑运算 and 与 or 或 not 非
*/
SELECT * FROM t_student WHERE sex = '男'
SELECT * FROM t_student WHERE sex <> '男'
SELECT * FROM t_student WHERE sex != '男'
SELECT * FROM t_student WHERE height >=170
-- 逻辑 and or not
-- and 连接多个条件 多个条件必须成立
SELECT * FROM t_student WHERE height >=170 AND height<=180
-- or 只需要成立其中一个条件即可
SELECT * FROM t_student WHERE height >=170 AND height<=180 OR sex ='男'
-- not 一般不单独使用 跟is一起使用
-- is null 为空的 is not null 不为空的
SELECT * FROM t_student WHERE height IS NULL
SELECT * FROM t_student WHERE height IS NOT NULL
/*
模糊查询:
LIKE :是否匹配于一个模式 一般和通配符搭配使用,可以判断字符型数值 或数值型;
通配符: % 任意多个字符,包含0个字符 _ 任意单个字符;
between and 两者之间,包含临界值;
in 判断某字段的值是否属于in列表中的某一项;
IS NULL(为空的)或 IS NOT NULL(不为空的)
*/
-- 王% 以王开头的任何字符串
SELECT * FROM t_student WHERE NAME LIKE '王%'
-- %3 以王结尾的任何字符串
SELECT * FROM t_student WHERE NAME LIKE '%3'
-- %李% 包含李的任何字符串
SELECT * FROM t_student WHERE NAME LIKE '%李%'
-- 王__ 以王开头的三个字符
SELECT * FROM t_student WHERE NAME LIKE '王__'
-- %四 以四结尾的两个字符
SELECT * FROM t_student WHERE NAME LIKE '_四'
-- %振% 包含四的三个字符
SELECT * FROM t_student WHERE NAME LIKE '_振_'
-- between A and B 两者之间 包含临界值
SELECT * FROM t_student WHERE height BETWEEN 170 AND 180
-- 类似于 <=180 and >=170
/*
多条语句查询:
UNION 的语法如下: [SQL 语句 1] UNION [SQL 语句 2]
UNION ALL 的语法如下: [SQL 语句 1] UNION ALL [SQL 语句 2]
当使用union 时,mysql 会把结果集中重复的记录删掉
而使用union all , mysql 会把所有的记录返回,且效率高于union 。
*/
-- 将多条语句查询的结果合并,去掉重复的
SELECT * FROM t_student WHERE sex ='女'
UNION
SELECT * FROM t_student WHERE height < 180
-- 将多条语句查询的结果合并,不去掉重复的
SELECT * FROM t_student WHERE sex ='女'
UNION ALL
SELECT * FROM t_student WHERE height < 180
/*
排序:
查询结果排序,使用 ORDER BY 子句排序 order by 排序列 ASC/DESC
asc代表的是升序,desc代表的是降序,如果不写,默认是升序
order by子句中可以支持单个字段、多个字段、表达式、函数、别名
*/
SELECT * FROM t_student ORDER BY num DESC -- 降序
-- 有条件 排序在条件的后面,对筛选后的结果进行排序
SELECT * FROM t_student WHERE num > 5 ORDER BY num DESC
SELECT * FROM t_student WHERE num > 5 ORDER BY height
-- 多个字段进行排序,当第一个相同时,对第二个排序,但是第一个排序优先
SELECT * FROM t_student WHERE num > 7 ORDER BY height,weight
/*
数量限制:
limit子句:对查询的显示结果限制数目 (sql语句最末尾位置)
SELECT * FROM table LIMIT offset rows;
SELECT * from table LIMIT 0,5;
*/
-- 数量限制,分页问题
-- limit 开始位置,查询的数量
SELECT * FROM t_student LIMIT 0,5
-- 查询男生中最高的
SELECT * FROM t_student WHERE sex = '男' ORDER BY height DESC LIMIT 0,1
/*
分组--统计 count()
分组查询:
select 分组函数,列(要求出现在group by的后面)
from 表
[where 筛选条件]
group by 分组的列表
[having 分组后的筛选]
[order by 子句]
注意:查询列表比较特殊,要求是分组函数和group by后出现的字段 分组查询中的筛选条件分为两类:
分组前筛选 原始表 group by 子句的前面 where
分组后筛选 分组后的结果集 group by的 后面 having
*/
-- 查询男生女生各自的人数 count(*)分组统计 分组统计男生组,女生组
SELECT sex,COUNT(*) FROM t_student GROUP BY sex
SELECT sex,SUM(height) FROM t_student GROUP BY sex
SELECT sex,AVG(height) FROM t_student GROUP BY sex
-- 查询男生和女生中人数最多的是那一个
SELECT sex,COUNT(*) FROM t_student WHERE height>160 GROUP BY sex HAVING COUNT(*)>2
SELECT
sex,
COUNT(*)
FROM
t_student
WHERE height > 160 -- 对原始数据条件进行筛选
GROUP BY sex -- 按照性别进行分组
HAVING COUNT(*)>1 -- 对分组后的个数进行大于1的判断与筛选
ORDER BY COUNT(*) DESC -- 对列表的数字进行排序
LIMIT 0,1 -- 选择最高的列
/*
条件查询:
使用WHERE 子句,将不满足条件的行过滤掉,WHERE 子句紧随 FROM 子句
语法:select <结果> from <表名> where <条件>
比较:
=, != 或<>, >, <, >=, <=
逻辑运算 and 与 or 或 not 非
*/
SELECT * FROM t_student WHERE sex = '男'
SELECT * FROM t_student WHERE sex <> '男'
SELECT * FROM t_student WHERE sex != '男'
SELECT * FROM t_student WHERE height >=170
-- 逻辑 and or not
-- and 连接多个条件 多个条件必须成立
SELECT * FROM t_student WHERE height >=170 AND height<=180
-- or 只需要成立其中一个条件即可
SELECT * FROM t_student WHERE height >=170 AND height<=180 OR sex ='男'
-- not 一般不单独使用 跟is一起使用
-- is null 为空的 is not null 不为空的
SELECT * FROM t_student WHERE height IS NULL
SELECT * FROM t_student WHERE height IS NOT NULL
/*
模糊查询:
LIKE :是否匹配于一个模式 一般和通配符搭配使用,可以判断字符型数值 或数值型;
通配符: % 任意多个字符,包含0个字符 _ 任意单个字符;
between and 两者之间,包含临界值;
in 判断某字段的值是否属于in列表中的某一项;
IS NULL(为空的)或 IS NOT NULL(不为空的)
*/
-- 王% 以王开头的任何字符串
SELECT * FROM t_student WHERE NAME LIKE '王%'
-- %3 以王结尾的任何字符串
SELECT * FROM t_student WHERE NAME LIKE '%3'
-- %李% 包含李的任何字符串
SELECT * FROM t_student WHERE NAME LIKE '%李%'
-- 王__ 以王开头的三个字符
SELECT * FROM t_student WHERE NAME LIKE '王__'
-- %四 以四结尾的两个字符
SELECT * FROM t_student WHERE NAME LIKE '_四'
-- %振% 包含四的三个字符
SELECT * FROM t_student WHERE NAME LIKE '_振_'
-- between A and B 两者之间 包含临界值
SELECT * FROM t_student WHERE height BETWEEN 170 AND 180
-- 类似于 <=180 and >=170
/*
多条语句查询:
UNION 的语法如下: [SQL 语句 1] UNION [SQL 语句 2]
UNION ALL 的语法如下: [SQL 语句 1] UNION ALL [SQL 语句 2]
当使用union 时,mysql 会把结果集中重复的记录删掉
而使用union all , mysql 会把所有的记录返回,且效率高于union 。
*/
-- 将多条语句查询的结果合并,去掉重复的
SELECT * FROM t_student WHERE sex ='女'
UNION
SELECT * FROM t_student WHERE height < 180
-- 将多条语句查询的结果合并,不去掉重复的
SELECT * FROM t_student WHERE sex ='女'
UNION ALL
SELECT * FROM t_student WHERE height < 180
/*
排序:
查询结果排序,使用 ORDER BY 子句排序 order by 排序列 ASC/DESC
asc代表的是升序,desc代表的是降序,如果不写,默认是升序
order by子句中可以支持单个字段、多个字段、表达式、函数、别名
*/
SELECT * FROM t_student ORDER BY num DESC -- 降序
-- 有条件 排序在条件的后面,对筛选后的结果进行排序
SELECT * FROM t_student WHERE num > 5 ORDER BY num DESC
SELECT * FROM t_student WHERE num > 5 ORDER BY height
-- 多个字段进行排序,当第一个相同时,对第二个排序,但是第一个排序优先
SELECT * FROM t_student WHERE num > 7 ORDER BY height,weight
/*
数量限制:
limit子句:对查询的显示结果限制数目 (sql语句最末尾位置)
SELECT * FROM table LIMIT offset rows;
SELECT * from table LIMIT 0,5;
*/
-- 数量限制,分页问题
-- limit 开始位置,查询的数量
SELECT * FROM t_student LIMIT 0,5
-- 查询男生中最高的
SELECT * FROM t_student WHERE sex = '男' ORDER BY height DESC LIMIT 0,1
/*
分组--统计 count()
分组查询:
select 分组函数,列(要求出现在group by的后面)
from 表
[where 筛选条件]
group by 分组的列表
[having 分组后的筛选]
[order by 子句]
注意:查询列表比较特殊,要求是分组函数和group by后出现的字段 分组查询中的筛选条件分为两类:
分组前筛选 原始表 group by 子句的前面 where
分组后筛选 分组后的结果集 group by的 后面 having
*/
-- 查询男生女生各自的人数 count(*)分组统计 分组统计男生组,女生组
SELECT sex,COUNT(*) FROM t_student GROUP BY sex
SELECT sex,SUM(height) FROM t_student GROUP BY sex
SELECT sex,AVG(height) FROM t_student GROUP BY sex
-- 查询男生和女生中人数最多的是那一个
SELECT sex,COUNT(*) FROM t_student WHERE height>160 GROUP BY sex HAVING COUNT(*)>2
SELECT
sex,
COUNT(*)
FROM
t_student
WHERE height > 160 -- 对原始数据条件进行筛选
GROUP BY sex -- 按照性别进行分组
HAVING COUNT(*)>1 -- 对分组后的个数进行大于1的判断与筛选
ORDER BY COUNT(*) DESC -- 对列表的数字进行排序
LIMIT 0,1 -- 选择最高的列
/*
子查询:出现在其他语句中的select语句
出现位置:
insert into后面:支持列子查询,表子查询
select后面:仅仅支持量子查询
form后面;支持表子查询
where后面:支持量子查询,列子查询,行子查询
按功能、结果的行列数不同
标量子查询(结果集只有一行一列)
列子查询(结果集只有一列多行)
行子查询(结果集有一行多列)(较少)
表子查询(结果集一般为多行多列)
*/
-- 在修改语句中使用了子查询,注意的是,子查询不是当前正在操作的表
UPDATE t_student SET NAME='aaa' WHERE num = (SELECT num FROM stu WHERE height = 180)
DELETE FROM t_student WHERE num = (SELECT num FROM stu WHERE height = 180)
-- 重点:在查询语句中使用字查询
-- 在一条sql中如果出现两个以上的表名时,可以表名定义别名
SELECT
ts.num,
(SELECT t.name FROM t_student t WHERE t.name = ts.name)
FROM
t_student ts
-- where 后面的子查询
-- 标量子查询
SELECT * FROM t_student WHERE height = (SELECT MAX(height) FROM t_student)
-- 列子查询 一列多行
SELECT * FROM t_student WHERE height IN (SELECT height FROM t_student WHERE height>170)
-- 列子查询 一列多行
SELECT * FROM t_student WHERE(height,weight)
= (SELECT MAX(height),MAX(weight) FROM t_student)
-- from后面 使用表子查询 返回多行多列
-- 查询男生,女生总人数大于1的
SELECT * FROM (SELECT sex, COUNT(*)c FROM t_student GROUP BY sex) t
WHERE t.c>3
多表设计_关联查询
为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的 规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计 要求的总结。目前关系数据库有5种范式:第一范式(1NF)、第二范式(2NF)、第 三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范 式(5NF,又称完美范式)。
第一范式(确保每列保持原子性):第一范式是最基本的范式。如果数据库表中的所有字段值都是不可分解的原子值,就 说明该 数据库表满足了第一范式。
第二范式就是要有主键,要求其他字段都依赖于主键:
第三范式就是要消除传递依赖,方便理解,可以看做是“消除冗余”
外键/添加约束键:
/*
外键:引用另外一个数据表的某条记录
外键列类型与主键列类型保持一致
数据表之间的关联/引用关系是依靠具体的主键(primary key)和外键(foreign key)建立起来 的。
*/
-- 先创建一个新的年级表
CREATE TABLE grade(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(4)
)`num`
ALTER TABLE t_student ADD gradeid INT AFTER mobile
-- 弱关联,人为定义的关系,在代码中并没有实际约束 删除其数据没有任何限制
-- 强关联 添加外键约束代码 t_student的约束键 grade的主键
ALTER TABLE t_student ADD CONSTRAINT fk_gradeid FOREIGN KEY(gradeid) REFERENCES grade(id)
-- 删除主键约束
ALTER TABLE t_student DROP FOREIGN KEY fk_gradeid
表与表的关系
/*
表与表之间的关系:
一对多
多对一
多对多
一对一(外键不重复)
*/
-- 创建课程表
CREATE TABLE course(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10)
)
-- 学生选课表(学生 课程之间的关系 一对多)
CREATE TABLE student_course(
student_num INT,
course_id INT,
CONSTRAINT fk_studentnum FOREIGN KEY (student_num) REFERENCES t_student(num)
CONSTRAINT fk_courseid FOREIGN KEY (course_id) REFERENCES course(id)
)
关联查询:
/*
关联查询:含义:又称多表查询,当查询的字段来自于多个表时,就会用到连接查询
学号,姓名,性别,年龄名称
*/
-- 笛卡尔乘积现象:表1有m行,表2有n行,结果=m*n
SELECT * FROM t_student,grade
-- 发生原因:没有有效的连接条件
-- 如何避免:添加有效的连接条件
-- 添加条件
SELECT * FROM t_student,grade WHERE gradeid = id
-- 多表时,为表定义表名,通过别名去调用表中的列,这样就不会重复
SELECT
s.num,
s.name,
s.sex,
g.name
FROM
t_student AS s,
grade AS g
WHERE
s.gradeid = g.id -- 先合并表,后筛选
-- 内关联 在关联时添加条件,吧满足条件的数据关联起来
SELECT s.num,s.name,s.sex,g.name FROM t_student s INNER JOIN grade g ON s.gradeid = g.id -- 等值连接
-- 非等值连接
ALTER TABLE t_student ADD score INT AFTER mobile
CREATE TABLE score_level(
lev_name VARCHAR(5),
lower_srcre INT,
upper_score INT
)
-- 内连接 非等值连接
SELECT
s.num,
s.name,
sl.lev_name
FROM
student s
INNER JOIN
score_level s1
ON
s.score BETWEEN s1.lower_score
AND s1.upper_score
-- 自关联 地区表
CREATE TABLE t_area(
id INT PRIMARY KEY,
NAME VARCHAR(4),
pid INT
)
SELECT ta.name,tp.name pname FROM t_area ta INNER JOIN t_area tp ON ta.pid = tp.id WHERE ta.id = 61010
SELECT
ta.name,
tp.name pname
FROM
t_area ta
INNER JOIN t_area tp
ON ta.pid = tp.id
WHERE ta.id = 61010q
-- 左外连接(left join) 无论关联条件是否成立,将左边表的数据全部查询出来
SELECT
s.num,
s.name,
s.sex,
g.name
FROM
t_student s
LEFT JOIN grade g
ON
s.gradeid = g.id
-- 右外连接(right join) 无论关联条件是否成立,将左边表的数据全部查询出来
SELECT
COUNT(s.gradeid),g.id,g.name
FROM
t_student s
RIGHT JOIN grade g
ON `id`
s.gradeid = g.id
GROUP BY g.id