简介
继上一篇博客我们继续来说关于MySQL的基础语句,
一、DDL(数据定义语言)
创建表的 SQL 语句
CREATE TABLE IF NOT EXISTS `runoob_tbl`(
`runoob_id` INT UNSIGNED AUTO_INCREMENT,
`runoob_title` VARCHAR(100) NOT NULL,
`runoob_author` VARCHAR(40) NOT NULL,
`submission_date` DATE,
PRIMARY KEY (`runoob_id`)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
如果你不想字段为 NULL 可以设置字段的属性为 NOT NULL,在操作数据表时如果输入该字段的数据为 NULL,就会报错。
AUTO_INCREMENT 定义列为自增的属性,一般用于主键,数值会自动加 1。
PRIMARY KEY 关键字用于定义列为主键。 您可以使用多列来定义主键,列间以逗号分隔。主键的作用是唯一标识表中的每条记录,且主键字段值不能重复、不能为 NULL
,助 AUTO_INCREMENT
能很好地实现自增主键来唯一区分记录
ENGINE 设置存储引擎,CHARSET 设置编码。
增加列
-- 增加列
alter table students add len int;
修改列
-- 修改列
alter table students modify len bigint;
删除列
-- 删除列
alter table students drop len;
修改表名
-- 修改表名
rename table students to students_tmp;
rename table students_tmp to students;
修改列名
-- 修改列名
alter table students change sex gender varchar(1);
修改字符集
-- 修改字符集
alter table students character set utf8;
删除表
-- 删除表
drop table students;
清空表
truncate students
二、DCL(数据控制语言)
插入数据
--1、插入一条数据
insert into students(name,age,sex,clazz) values('施笑槐',22,'女','文科六班');
--2、插入多条数据
insert into students(name,age,sex,clazz) values
('吕金鹏',22,'男','文科六班'),
('单乐蕊',22,'女','理科六班'),
('葛德曜',22,'男','理科三班'),
('宣谷芹',22,'女','理科五班'),
('边昂雄',22,'男','理科二班');
-- 3、不指定字段名插入数据
insert into students values (10,'吕金鹏',22,'男','文科六班');
- 插入的数据应与字段的数据类型相同。
- 数据的大小应在列的规定范围内,例如:不能将一个长度为 80 的字符串加入到长度为 40 的列中。
- 在 values 中列出的数据位置必须与被加入的列的排列位置相对应。
- 字符和日期型数据应包含在单引号中。
- 插入空值:不指定或
insert into table value(null)
这里没有设置id列,对于id列如果设置了自增,一般会自己增加,不需要给定值,如果没有设置就需要我们自己添加,若不添加就为空。除了主键不可以一样其他的相同的内容是可以的
更新数据
-- 修改全表
update students set clazz="文科二班";
-- 带条件修改数据
update students set age=24 where id='1500100016';
-- 更新多列
update students set age=24,clazz='文科一班' where id='1500100016';
删除数据
-- 删除所有数据
delete from students;
-- 删除指定数据
delete from students where sex='男';
三、DQL (数据查询语)
查询是数据库最重要的语句
select
-- 1、选择所有字段
select * from students;
查询 students
表中所有字段的数据,*
是通配符,代表 “所有列” 。
-- 2、选择指定字段
select id,name from students;
仅查询 students
表的 id
和 name
这指定字段的数据,减少返回的列数。
--3、在select中处理数据
-- as 取别名
select id,name,age+10 as age from students;
select id,name,age,sex,clazz,substring(clazz,1,2) as type from students;
查询 id
、name
字段,同时对 age
字段做运算(加 10),并用 as
给运算后的结果取别名 age
(也可省略 as
,直接写 age+10 age
)
查询 id
、name
、age
、sex
、clazz
字段,同时用 substring
函数截取 clazz
字段的子串(从第 1 位开始,取 2 个字符),并用 as
取别名 type
。
--4、在select中进行聚合计算
-- 全局聚合
-- 1不为null,所有每一行都会计数
select count(1) as num from students;
-- 如果一行所有的字段都为null,就不计数
select count(*) as num from students;
-- 如果字段值为null,就不计数
select count(clazz) as num from students;
select count(null) as num from students;
count(1)
逻辑:1
是常量,不会为NULL
。遍历表时,每一行都能 “匹配” 这个常量,所以不管某行字段是否为NULL
,都会计数 。ount(*)
逻辑:*
代表 “所有列” ,但计数逻辑是统计 “行的数量” 。只有当一行所有字段都为NULL
(极端情况,实际表设计一般有非空约束避免),才不计入统计;只要行存在(哪怕部分字段NULL
),就计数 。count(字段名)
逻辑:只统计该字段值不为NULL
的行数 。如果某行的clazz
字段是NULL
,这一行就不会被计入结果 。- 因为
count
函数遇到明确的NULL
入参,会直接返回0
(count
对NULL
不计数 )。不管students
表有多少行,结果都是0
。
-- 组内聚合
select sex,count(1) as num
from students
group by sex;
- 先按
sex
字段分组(比如sex
是 “男”“女” ,就分成两组 ),然后对每组数据,用count(1)
统计 “组内的行数” ,最终结果会展示 “性别(sex
)” 和 “对应性别的人数(num
)” 。 group by sex
:分组依据,把表拆成多个小 “子集”(按sex
不同值划分 )。count(1) as num
:对每个分组,统计行数(因为count(1)
不关心字段NULL
,只要组内有行就计数 ),并把结果叫num
,代表 “每组的数量” 。
where
where 子句 -- 用于筛选过滤
类别 | 运算符 / 关键字 | 说明 | 示例 / 补充 |
---|---|---|---|
比较运算符 | > < <= >= = <> | 大于、小于、大于 (小于) 等于、不等于 | - |
比较运算符 | between ...and... | 显示在某一区间的值 | - |
比较运算符 | in(set) | 显示在 in 列表中的值 | in(100,200) |
比较运算符 | like | 模糊查询,搭配 % (多字符)、_ (单字符) | like '张%' (查姓张开头数据 ) |
比较运算符 | is null | 判断字段是否为空 | - |
逻辑运算符 | and | 多个条件同时成立 | where age>18 and sex='男' |
逻辑运算符 | or | 多个条件任一成立 | where score>90 or grade='A' |
逻辑运算符 | not | 条件取反,不成立 | where not(income>10000) |
单条件
-- 1、单条件
-- 按主键/唯一标识精确查询:id值完全匹配'1500100084'的行,返回所有字段(*)
select * from students where id='1500100084';
-- > >= < <= !=
-- 数值范围筛选:age大于23的行(> >= < <= != 是基础比较运算符,可按需替换)
select * from students where age > 23;
-- 使用函数
-- 使用substring函数截取clazz字段的前2个字符,判断是否等于'文科'
select * from students where substring(clazz,1,2) = '文科';
-- 模糊匹配
-- 左匹配:clazz以'文科'开头(%代表任意多个字符,放在后面),如“文科一班”“文科二班”
select * from students where clazz like '文科%';
-- 右匹配:clazz以'一班'结尾(%放在前面),如“文科一班”“理科一班”
select * from students where clazz like '%一班';
-- 包含
-- 筛选clazz是'文科一班'或'文科二班'的行(IN里的内容是“允许的值集合”)
select * from students where clazz in ('文科一班','文科二班');
-- 筛选clazz不是'文科一班'且不是'文科二班'的行(NOT IN 取反)
select * from students where clazz not in ('文科一班','文科二班');
-- is null
-- 筛选clazz字段为NULL(未赋值)的行
select * from students where clazz is null;
-- 筛选clazz字段是“空字符串”(值为'',和NULL不同,是主动填了空内容 )的行
select * from students where clazz = '';
-- between and
-- 筛选age在23到24之间(包含23和24)的行,等价于 age >=23 and age <=24
select * from students where age between 23 and 24;
NULL
vs 空字符串:NULL
是 “未定义、无值”;- 空字符串(
''
)是 “有值,但值为空” 。
多条件
-- 2、多条件
select * from students where clazz = '文科一班' and age = 23 and sex = '男';
select * from students where (clazz = '文科一班' and age = 23) or sex = '男';
clazz = '文科一班'
:筛选班级是 “文科一班” 的行;age = 23
:同时年龄等于 23;sex = '男'
:同时性别是 “男”;AND
:要求所有条件同时满足,结果是 “文科一班、23 岁、男性” 的学生。
取反
-- 3、取反
select * from students where not(sex = '男');
- 先判断
sex = '男'
(筛选性别是男的行); NOT
:对条件取反,最终结果是性别不是男的行(即女学生,或sex
为NULL
的行,需看表数据 )。
这些语句的核心是 通过 AND
、OR
、NOT
组合条件,实现更复杂的筛选逻辑:
AND
要求 “同时满足”,OR
要求 “任一满足”,NOT
是 “条件取反”;- 括号可调整条件优先级,让逻辑更贴合业务需求(比如多条件组合时,明确哪些条件要先联动 )。
还有一个DCL(数据控制语言)指用于设置用户权限和控制事务语句,如 grant,revoke,if…else,while,begin transaction暂时还不讲,先把sql的基础东西说完。
四、MySQL的内置函数(属于DQL)
1.单行函数
函数名称 | 作用 |
---|---|
LENGTH | 计算字符串长度函数,返回字符串的字节长度 |
CONCAT | 合并字符串函数,返回结果为连接参数产生的字符串,参数可以使一个或多个 |
INSERT | 替换字符串函数 |
LOWER | 将字符串中的字母转换为小写 |
UPPER | 将字符串中的字母转换为大写 |
LEFT | 从左侧截取字符串,返回字符串左边的若干个字符 |
RIGHT | 从右侧截取字符串,返回字符串右边的若干个字符 |
TRIM | 删除字符串左右两侧的空格 |
REPLACE | 字符串替换函数,返回替换后的新字符串 |
SUBSTRING | 截取字符串,返回从指定位置开始的指定长度的字符串 |
REVERSE | 字符串反转(逆序)函数,返回与原始字符串顺序相反的字符串 |
2.日期函数
函数名称 | 作用 |
---|---|
CURDATE 和 CURRENT_DATE | 两个函数作用相同,返回当前系统的日期值 |
CURTIME 和 CURRENT_TIME | 两个函数作用相同,返回当前系统的时间值 |
NOW 和 SYSDATE | 两个函数作用相同,返回当前系统的日期和时间值 |
UNIX_TIMESTAMP | 获取 UNIX 时间戳函数,返回一个以 UNIX 时间戳为基础的无符号整数 |
FROM_UNIXTIME | 将 UNIX 时间戳转换为时间格式,与 UNIX_TIMESTAMP 互为反函数 |
MONTH | 获取指定日期中的月份 |
MONTHNAME | 获取指定日期中的月份英文名称 |
DAYNAME | 获取指定日期对应的星期几的英文名称 |
DAYOFWEEK | 获取指定日期对应的一周的索引位置值 |
WEEK | 获取指定日期是一年中的第几周,返回值的范围是否为 0~52 或 1~53 |
DAYOFYEAR | 获取指定日期是一年中的第几天,返回值范围是 1~366 |
DAYOFMONTH | 获取指定日期是一个月中是第几天,返回值范围是 1~31 |
YEAR | 获取年份,返回值范围是 1970~2069 |
TIME_TO_SEC | 将时间参数转换为秒数 |
SEC_TO_TIME | 将秒数转换为时间,与 TIME_TO_SEC 互为反函数 |
DATE_ADD 和 ADDDATE | 两个函数功能相同,都是向日期添加指定的时间间隔 |
DATE_SUB 和 SUBDATE | 两个函数功能相同,都是向日期减去指定的时间间隔 |
ADDTIME | 时间加法运算,在原始时间上添加指定的时间 |
SUBTIME | 时间减法运算,在原始时间上减去指定的时间 |
DATEDIFF | 获取两个日期之间间隔,返回参数 1 减去参数 2 的值 |
FORMAT | 格式化指定的日期,根据参数返回指定格式的值 |
DAY | 获取指定日期在一周内的对应的工作日索引 |
3.数值函数
函数名称 | 作用 |
---|---|
ABS | 求绝对值 |
SQRT | 求二次方根 |
MOD | 求余数 |
CEIL 和 CEILING | 两个函数功能相同,都是返回不小于参数的最小整数,即向上取整 |
FLOOR | 向下取整,返回值转化为一个 BIGINT |
RAND | 生成一个 0~1 之间的随机数,传入整数参数是,用来产生重复序列 |
ROUND | 对所传参数进行四舍五入 |
SIGN | 返回参数的符号 |
POW 和 POWER | 两个函数的功能相同,都是所传参数的次方的结果值 |
SIN | 求正弦值 |
ASIN | 求反正弦值,与函数 SIN 互为反函数 |
COS | 求余弦值 |
ACOS | 求反余弦值,与函数 COS 互为反函数 |
TAN | 求正切值 |
ATAN | 求反正切值,与函数 TAN 互为反函数 |
4.聚合函数
函数名称 | 作用 | 示例 |
---|---|---|
COUNT | 用于计算表中的行数,或者满足特定条件的行数。COUNT (字段名) 会忽略字段值为 NULL 的行,COUNT (*) 和 COUNT (常量) 会统计所有行 | SELECT COUNT(*) FROM students; (统计 students 表的总行数)SELECT COUNT(age) FROM students; (统计 students 表中 age 字段不为 NULL 的行数) |
SUM | 对数值类型的字段进行求和操作,忽略 NULL 值 | SELECT SUM(score) FROM scores; (计算 scores 表中 score 字段的总和) |
AVG | 计算数值类型字段的平均值,忽略 NULL 值 | SELECT AVG(age) FROM students; (计算 students 表中 age 字段的平均值) |
MAX | 返回指定字段的最大值,若字段值全为 NULL,则返回 NULL | SELECT MAX(price) FROM products; (找出 products 表中 price 字段的最大值) |
MIN | 返回指定字段的最小值,若字段值全为 NULL,则返回 NULL | SELECT MIN(weight) FROM goods; (找出 goods 表中 weight 字段的最小值) |
GROUP_CONCAT | 将分组中的值连接成一个字符串,可通过参数指定分隔符等。默认分隔符是逗号 | SELECT class, GROUP_CONCAT(name) FROM students GROUP BY class; (按 class 分组,将每个班级的学生 name 连接成字符串) |
STDDEV_POP 或 STDDEV_SAMP | 前者计算总体标准偏差,后者计算样本标准偏差,用于衡量数据的离散程度,忽略 NULL 值 | SELECT STDDEV_POP(score) FROM exam_results; (计算 exam_results 表中 score 字段的总体标准偏差) |
VARIANCE 或 VAR_POP 或 VAR_SAMP | VARIANCE 和 VAR_POP 计算总体方差,VAR_SAMP 计算样本方差,用于衡量数据的离散程度,忽略 NULL 值 | SELECT VARIANCE(income) FROM employees; (计算 employees 表中 income 字段的总体方差) |