MySQL语法学习笔记
学习之道,非尽心竭力者不能进也!我是唧唧又唧唧,欢迎查看我的笔记,有问题欢迎交流探讨。
SQL是一种结构查询语言,用于查询关系数据库的标准语言,包括若干关键字和一致的语法,便于数据库元件(表、索引、字段等)的建立和操纵。
目录
1.MySQL建库
1.1建库语句
create database emp #建库 名为 emp
default character set utf-8 #设置该库的默认编码格式为 utf-8
collate utf8_general_ci; #设置数据库校对规则。不区分大小写
示例中 utf8_bin将字符串中的每一个字符用二进制数据存储,区分大小写。utf8_genera_ci不区分大小写,ci为case insensitive的缩写,即大小写不敏感。utf8_general_cs区分大小写,cs为case sensitive的缩写,即大小写敏感。
1.2删除库
drop database emp;
2.建表
2.1建表模板
CREATE TABLE customers
(
cust_id int NOT NULL AUTO_INCREMENT,
cust_name char(50) NOT NULL ,
cust_address char(50) NULL ,
cust_city char(50) NULL ,
cust_state char(5) NULL ,
cust_zip char(10) NULL ,
cust_country char(50) NULL ,
cust_contact char(50) NULL ,
cust_email char(255) NULL ,
PRIMARY KEY (cust_id)
) ENGINE=InnoDB;
2.2 主键(PRIMARY KEY)
主键值必须唯一:表中的每个行必须具有唯一的主键值。
如果主键使用单个列,则它的值必须唯一。
迄今为止我们看到的CREATE TABLE例子都是用单个列作为主键。
PRIMARY KEY (cust_id)
如果使用多个列,则这些列的组合值必须唯一 。
创建由多个列组成的主键,应该以逗号分隔的列表给出各列名。
PRIMARY KEY (order_num,order_item)
主键中只能使用不允许NULL值的列,允许NULL值的列不能作为唯一标识。
2.3AUTO_INCREMENT
AUTO_INCREMENT定义列为自增的属性,一般用于主键,每次执行一个INSERT操作时,数值会自动加1
使用的最简单的编号是下一个编号,所谓下一个编号是大于当前最大编号的编号。例如,如果cust_id的最大编号为10005,则插入表中的下一个顾客,可以具有等于10006的 cust_id 。
2.4 默认值
如果在插入行时没有给出值,MySQL允许指定此时使用的默认值。默认值 用CREATE TABLE语句的列定义中的DEFAULT关键字指定
2.5 存储引擎(ENGINE=InnoDB)
与其他DBMS一样,MySQL有一个具体管理和处理数据的内部引擎。
在你使用CREATE TABLE语句时,该引擎具体创建表。
而在你使用SELECT语句 或进行其他数据库处理时,该引擎在内部处理你的请求。
多数时候,此引擎 都隐藏在DBMS内,不需要过多关注它。
以下是几个需要知道的引擎:
-
InnoDB是一个可靠的事务处理引擎,它不支持全文本搜索;
-
MEMORY在功能等同于MyISAM,但由于数据存储在内存(不是磁盘)中,速度很快(特别适合于临时表);
-
MyISAM是一个性能极高的引擎,它支持全文本搜索但不支持事务处理 。
2.6 ALTER TABLE 语句
ALTER TABLE 语句用于在已有的表中添加、删除或修改列。
-- 表中添加列
ALTER TABLE customers
ADD cust_phone char(10)
-- 删除表中的列(请注意,某些数据库系统不允许这种在数据库表中删除列的方式)
ALTER TABLE customers
DROP COLUMN cust_phone
-- 改变表中列的数据类型
-- 修改数量字段的默认值为80
ALTER TABLE customers
MODIFY COLUMN quantity int(11) null default 80 after prod_id
2.7 删除表
DROP TABLE customers
3.SQL处理数据的基本方法
3.1 数据检索(select 语句)
Select 语句语法
Select 检索所有列
Select 检索单个列
Select 检索不同行
Select 的结果限定
# 描述表
DESC products;
# select 语句 检索所有列
SELECT * FROM products;
# select 语句 检索指定的多个列
SELECT prod_id,prod_name,prod_price FROM products;
# select 语句 检索指定的一个列
SELECT vend_id FROM products;
# 去重,DISTINCT 关键词用于返回唯一不同的值
SELECT distinct vend_id FROM products;
# 第1行开始,取前3行
SELECT * FROM products limit 3;
# 第4行开始,取3行
SELECT * FROM products limit 3,3;
3.2 数据排序
ORDER BY 关键字用于对结果集按照一个列或者多个列进行排序。
ORDER BY 关键字默认按照升序对记录进行排序。如果需要按照降序对记录进行排序,可以使用 DESC 关键字。
# 先查看一下这次用的products表
SELECT * from products;
# 单个字段的排序 升序 降序
SELECT prod_id,prod_price from products
ORDER BY prod_price;
# 默认(ASC)是升序,desc 是降序,默认可以不写
SELECT prod_id,prod_price from products
ORDER BY prod_price desc;
# 默认排序a-z ,反序就是z-a
SELECT prod_id,prod_price from products
ORDER BY prod_name desc;
# 多字段排序
SELECT prod_name,prod_price from products
ORDER BY prod_price,prod_name;
# 找出最便宜的产品
SELECT prod_name,prod_price from products
ORDER BY prod_price LIMIT 1;
# 找出最贵的产品
SELECT * from products
ORDER BY prod_price DESC LIMIT 1;
3.3 数据过滤
数据库表一般包含大量的数据,很少需要检索表中所有行。
通常只会根据特定操作或报告的需要提取表数据的子集。
只检索所需数据需要指定搜索条件(search criteria)
搜索条件也称为过滤条件(filter condition)。
在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。
WHERE子句在表名 (FROM子句)之后给出。
3.3.1 使用Where子句
检查单个值
不匹配检查
# 筛选价格是2.5的产品
select * from products where prod_price = 2.5;
# 筛选价格是2.5的产品,并只显示特定的字段
select prod_name,prod_price from products
where prod_price = 2.5;
# WHERE 条件操作符:=、>、<、>=、<=、<>/!=、between * and *(包含首尾)
select prod_name,prod_price from products
where prod_price >= 2.5 and prod_price <10
order by prod_price;
select prod_name,prod_price from products
where prod_price BETWEEN 2.5 and 10
order by prod_price;
练习:
找出价格低于10元的产品
找出价格不是供应商1003制造的产品
找出供应商1001,1003 制造的产品
select prod_name,prod_price from products
where prod_price < 10
order by prod_price;
select vend_id,prod_name,prod_price from products
where vend_id != 1003
order by prod_price;
select vend_id,prod_name,prod_price from products
where vend_id = 1001 or vend_id = 1003;
order by prod_price;
3.3.2 空值检查
select * from products
where prod_desc is null
3.3.3 And、Or、In、Not操作及其计算次序
- AND & OR 运算符用于基于一个以上的条件对记录进行过滤。
- 如果第一个条件和第二个条件都成立,则 AND 运算符显示一条记录。
- 如果第一个条件和第二个条件中只要有一个成立,则 OR 运算符显示一条记录。
- 先and语句后执行or语句
# where 组合子句之 and 操作(交集)
select * from products where vend_id=1003 and prod_price <=10
ORDER BY prod_price;
# where 组合子句之 or 操作(并集)
select * from products where vend_id=1003 or vend_id =1002;
# where 组合子句之 AND 和 OR 的结合使用(使用圆括号来组成复杂的表达式)
SELECT * FROM products
WHERE prod_price <=10
AND (vend_id=1003 or vend_id =1002);
- IN 操作符允许在 WHERE 子句中规定多个值
- ‘=’ 规定一个值
# where 组合子句之 in 操作
select * from products where
vend_id in (1001,1005,1002);
# where 组合子句之 in 与 = 的转换
select * from products where
vend_id = 1001 or vend_id = 1005 or vend_id = 1002;
# where 组合子句之 not 操作
select * from products where
vend_id not in (1002);
- not操作
# where 组合子句之 not 操作
select * from products where
vend_id not in (1002);
3.3.4 通配符(模糊匹配)
- 通配符可用于替代字符串中的任何其他字符。
- % 替代 0 个或多个字符
- “_” 替代1个字符。
- LIKE 操作符用于在 WHERE 子句中搜索列中的指定模式
# 找到以 jet开头的产品
select prod_id ,prod_name from products
where prod_name like 'jet%'
select prod_id ,prod_name from products
where prod_name like '%anvil%'
select prod_id ,prod_name from products
where prod_name like 's%e'
select prod_id ,prod_name from products
where prod_name like '_ ton anvil'
select prod_id ,prod_name from products
where prod_name like '__ ton anvil'
注意:
- 不要过度使用通配符,如果其他操作符能达到相同的目的,应优先使用其他操作符。
- 非必要情况下,不要把通配符用在搜索模式的开始处,因为这样搜索起来是最慢的。
- 仔细注意通配符的位置,如果放错地方可能不会返回想要的数据。
4.SQL处理数据高级方法
4.1正则表达式
正则表达式 用特殊的字符集合与一个文本串进行比较,过滤检索出想要的数据
- 正则表达式是用来匹配文本的特殊的串(字符集合)
- 如果你想从一个文本文件中提取电话号码,可以使用正则表达式。
- 如果你需要查找名字中间有数字的所有文件,可以使用一个 正则表达式。
- 如果你想在一个文本块中找到所有重复的单词,可以使用一 个正则表达式。
- 如果你想替换一个页面中的所有URL为这些URL的实际 HTML链接,也可以使用一个正则表达式(对于最后这个例子,或者是两个正则表达式)。
4.1.1基本字符串匹配
# 使用 like 关键字和通配符 %
select prod_name from products
where prod_name like '%1000';
# 使用正则表达式 REGEXP
select prod_name from products
where prod_name REGEXP '1000';
# 可以检索出prod_name 中所有含有‘1000’的行
4.1.2 特殊字符“ .” 的使用
“ .” 在正则表达式中表示匹配任意一个字符
# 使用 like 关键字和通配符 _
select prod_name from products
where prod_name like 'JetPack _000';
# 使用正则表达式 REGEXP 和特殊字符“.”
select prod_name from products
where prod_name REGEXP '.000';
- 在这里会不会有人觉得奇怪,“.” 表示的是匹配任意一个字符,但结果显示的 JetPack 1000、JetPack
2000,000的前面可不止一个字符,为什么能这样匹配呢? - 好好理解这句话 “正则表达式是用来匹配文本的特殊的串”
你会发现利用正则表达式我们可以匹配出相应字段中所有含有需要匹配的文本的行。例子中我们需要匹配的是‘.000’,.
可以代表任何一个字符,所以我们把 JetPack 1000、JetPack 2000
匹配出来了,1000,2000就是我们想要匹配的文本。不管他们前后还有没有别的字符都会被查询的到。 - 对比 关键字 like 与通配符的联合使用就无法达到这种效果了。
4.1.3 使用 or 进行匹配(条件匹配)
此 or 不是真的 or ,而是使用竖线 “|” 表示搜索 两个匹配文本串的其中一个
# 检索prod_name 中所有含有‘1000’或者‘2000’的行
select prod_name from products
where prod_name REGEXP '1000|2000';
正则表达式中可使用多个 or 条件
select prod_name from products
where prod_name REGEXP '1000|2000|anvil';
4.1.4 []匹配
”[]“代表需要匹配[]中所包含的任意一个字符
4.1.4.1 匹配几个字符之一
select prod_name from products
where prod_name REGEXP '[12] ton';
这里使用正则表达式 [12] ton 。 [12] 定义了一组字符1,2;可以匹配 1 ton 或者 2 ton.
其实,[] 是另一种形式的 or 语句
4.1.4.2 匹配范围
[]匹配[]中所包含的任意一个字符
[0-9] 匹配0到9的任意数字字符
[1-3] 匹配1到3的任意数字字符
[6-9] 匹配6到9的任意数字字符
[a-z] 匹配a到z 的任意字母字符
select prod_name from products
where prod_name REGEXP '[1-5] ton';
# 匹配1到5任意一个数字,所以返回了1 ton、2 ton、5 ton
4.1.4.3 排他符[^]
- [^] 匹配未包含在[]中的任意字符。即,将匹配除指定字符外的任何东西。
- 在集合开始处放置一个 ^
- 例如,[^12],会匹配除1,2外的任何东西
select prod_name from products
where prod_name REGEXP '[^345] ton'
# 不会出现 3 ton、4 ton、5 ton
4.1.5 特殊字符的匹配(. [] | -)
匹配特殊字符(. [] | -)时,需要使用 转义符(两个反斜杠\\)
\\- 表示查找 -,\\.表示查找 .
select prod_name from products
where prod_name REGEXP '\\.';
#查找 .
\\也用来引用元字符(具有特殊含义的字符)
元字符 | 说明 |
---|---|
\\f | 换页 |
\\n | 换行 |
\\r | 回车 |
\\t | 制表 |
\\v | 纵向制表 |
4.1.6 匹配字符类
[:digit:] 任意数字 (同[0-9])
[:alnum:] 任意字母和数字 (同[a-zA-Z0-9])
[:alpha:] 任意字母 (同[a-zA-Z])
[:lower:] 任意小写字母 (同[a-z])
[:upper:] 任意大写字母 (同[A-Z])
select prod_name from products
where prod_name REGEXP '[[:digit:]]{4}'
4.1.7 匹配多个实例,重复元字符
元字符 | 说明 |
---|---|
* | 0个或多个匹配 |
+ | 1个或多个匹配 (同{1,}) |
? | 0个或1个匹配(同{0,1}) |
{n} | 指定数目的匹配 |
{n,} | 不少于指定数目的匹配 |
{n,m} | 匹配数目的范围(m不超过255) |
#匹配连在一起的任意4位数字的行
select prod_name from products
here prod_name REGEXP '[[:digit:]]{4}';
select prod_name from products
where prod_name REGEXP '[0-9][0-9][0-9][0-9]';
select prod_name from products
where prod_name REGEXP '\\([0-9] sticks?\\)';
# \\( 、\\) 使用转义符,[0-9]匹配1到9任意数字
#s? 中 使用 ?表示 s 可以出现0次或1次,所以出现了结果stick、sticks
- ? 匹配它前面的任何字符的0次或1次出现,换句话说,?前面的字符有(1个)或者没有(0个)都能被匹配
4.1.8 定位符,元字符
元字符 | 说明 |
---|---|
^ | 文本的开始 |
$ | 文本的结尾 |
[[:<:]] | 词的开始 |
[[:>:]] | 词的结尾 |
select prod_name from products
where prod_name REGEXP '^[\\.]'
在这里,我们可以回顾一下排他符[^ ]
总结一下^ 的用途:
1.在集合中 [^],表示不匹配集合所包含的字符
2.匹配输入字符串的开始位置。
4.2 计算字段
4.2.1 什么是计算字段
- 计算字段不实际存在于数据库表中,而是运行时在select语句内创建的字段(列),可以使用别名。
4.2.2 拼接字段
- 将值联结到一起构成单个值
- concat() 函数,可以拼接字符串,可以拼接两个列。拼接的串之间用逗号分隔
SELECT * FROM vendors;
SELECT CONCAT(vend_city,' (',vend_country,')') from vendors;
- 使用别名:使用 as 关键字
- as 后接着你想要赋予字段的名字
SELECT CONCAT(vend_city,' (',vend_country,')') as '位置'
from vendors;
4.2.3 执行算术计算
- 对检索出来的数据进行算术计算
select prod_id,quantity * item_price as total
from orderitems
ORDER BY total;
- MySQL算术操作符
操作符 | 说明 |
---|---|
+ | 加 |
- | 减 |
* | 乘 |
/ | 除 |
4.3 MySQL数据处理函数
函数类型 | 说明 |
---|---|
文本函数 | 处理文本串(如删除或填充值,转换值得大小写) |
数值函数 | 用于数值数据上的算术操作(如返回绝对值,进行代数计算 ) |
日期和时间函数 | 处理日期和时间值并从这些值中提取特定的成分(如返回两个日期之差,检查日期有效性等) |
系统函数 | 返回DBSM正使用的特殊信息(如返回用户登录信息,检查版本细节) |
4.3.1 文本处理函数
函数 | 作用 |
---|---|
Rtrim(s) | 去除字符串右边的空格 |
Ltrim(s) | 去除字符串左边的空格 |
TRIM(s) | 去除字符串开头结尾的空格 |
upper(s) | 定义字符串全部大写 |
UCASE(s) | 将字符串转成大写 |
lower(s) | 定义字符串全部小写 |
LCASE(s) | 将字符串全部转成小写 |
ASCII(s) | 返回字符串 s 的第一个字符的 ASCII 码 |
CHAR_LENGTH(s) | 返回字符串s的字符数 |
CHARACTER_LENGTH(s) | 返回字符串s的字符数 |
CONCAT(s1,s2…sn) | 合并字符串 |
MID(s,n,len) | 从字符串 s 的 n 位置截取长度为 len 的子字符串,同 SUBSTRING(s,n,len) |
substring(s,n,len) | 从字符串 s 的 n 位置截取长度为 len 的子字符串 |
SPACE(n) | 返回n个空格 |
RIGHT(s,n) | 返回字符串 s 的后 n 个字符 |
LPAD(s1,len,s2) | 在字符串 s1 的开始处填充字符串 s2,使字符串长度达到 len |
RPAD(s1,len,s2) | 在字符串 s1 的结尾处添加字符串 s2,使字符串的长度达到 len |
INSERT(s1,x,len,s2) | 字符串 s2 替换 s1 的 x 位置开始长度为 len 的字符串 |
FORMAT(x,n) | 函数可以将数字 x 进行格式化 “#,###.##”, 将 x 保留到小数点后 n 位,最后一位四舍五入。 |
SELECT UPPER(RTRIM(vend_name))as vend_name FROM vendors;
SELECT vend_name,ASCII(vend_name) FROM vendors;
4.3.2 数值函数
函数 | 说明 |
---|---|
ABS(x) | 返回 x 的绝对值 |
ACOS(x) | 求反余弦值(参数是弧度) |
ASIN(x) | 求反正弦值(参数是弧度) |
ATAN(x) | 求反正切值(参数是弧度) |
AVG(expression) | 返回一个表达式的平均值,expression 是一个字段 |
CEIL(x) | 返回大于或等于 x 的最小整数 |
CEILING(x) | 返回大于或等于 x 的最小整数 |
COS(x) | 求余弦值(参数是弧度) |
COT(x) | 求余切值(参数是弧度) |
COUNT(expression) | 返回查询的记录总数,expression 参数是一个字段或者 * 号 |
DEGREES(x) | 将弧度转换为角度 |
n DIV m | 整除,n 为被除数,m 为除数 |
EXP(x) | 返回 e 的 x 次方 |
FLOOR(x) | 返回小于或等于 x 的最大整数 |
GREATEST(expr1, expr2, expr3, …) | 返回列表中的最大值 |
LEAST(expr1, expr2, expr3, …) | 返回列表中的最小值 |
LN() | 返回数字的自然对数,以 e 为底。 |
LOG(x) 或 LOG(base, x) | 返回自然对数(以 e 为底的对数),如果带有 base 参数,则 base 为指定带底数。 |
LOG10(x) | 返回以 10 为底的对数 |
LOG2(x) | 返回以 2 为底的对数 |
MAX(expression) | 返回字段 expression 中的最大值 |
MIN(expression) | 返回字段 expression 中的最小值 |
MOD(x,y) | 返回 x 除以 y 以后的余数 |
PI() | 返回圆周率(3.141593) |
POW(x,y) | 返回 x 的 y 次方 |
POWER(x,y) | 返回 x 的 y 次方 |
RADIANS(x) | 将角度转换为弧度 |
RAND() | 返回 0 到 1 的随机数 |
ROUND(x) | 返回离 x 最近的整数 |
SIGN(x) | 返回 x 的符号,x 是负数、0、正数分别返回 -1、0 和 1 |
SIN(x) | 求正弦值(参数是弧度) |
SQRT(x) | 返回x的平方根 |
SUM(expression) | 返回指定字段的总和 |
TAN(x) | 求正切值(参数是弧度) |
TRUNCATE(x,y) | 返回数值 x 保留到小数点后 y 位的值(与 ROUND 最大的区别是不会进行四舍五入) |
4.3.3 日期函数
函数 | 说明 |
---|---|
ADDDATE(d,n) | 计算起始日期 d 加上 n 天的日期 |
ADDTIME(t,n) | n 是一个时间表达式,时间 t 加上时间表达式 n |
CURDATE() | 返回当前日期 |
CURRENT_DATE() | 返回当前日期 |
CURRENT_TIME | 返回当前时间 |
CURRENT_TIMESTAMP() | 返回当前日期和时间 |
CURTIME() | 返回当前时间 |
DATE() | 从日期或日期时间表达式中提取日期值 |
DATEDIFF(d1,d2) | 计算日期 d1->d2 之间相隔的天数 |
DAY(d) | 返回日期值 d 的日期部分 |
DAYNAME(d) | 返回日期 d 是星期几,如 Monday,Tuesday |
DAYOFMONTH(d) | 计算日期 d 是本月的第几天 |
DAYOFWEEK(d) | 日期 d 今天是星期几,1 星期日,2 星期一,以此类推 |
DAYOFYEAR(d) | 计算日期 d 是本年的第几天 |
NOW() | 返回当前日期和时间 |
WEEK(d) | 计算日期 d 是本年的第几个星期,范围是 0 到 53 |
YEAR(d) | 返回年份 |
4.3.4 系统函数
函数 | 说明 |
---|---|
VERSION() | 返回数据库的版本号 |
USER() | 返回当前用户 |
NULLIF(expr1, expr2) | 比较两个字符串,如果字符串 expr1 与 expr2 相等 返回 NULL,否则返回 expr1 |
ISNULL(expression) | 判断表达式是否为 NULL |
IFNULL(v1,v2) | 如果 v1 的值不为 NULL,则返回 v1,否则返回 v2。 |
4.4 数据汇聚
- 确定表中行数(或者满足某个条件或包含某个特定值的行数)。
- 获得表中行组的和。
- 找出表列(或所有行或某些特定的行)的最大值、最小值和平均值。
- SQL汇聚函数 AVG()、COUNT()、MAX()、MIN()、SUN()
- 汇聚函数:运行在行组上,计算和返回单个值的函数
汇聚函数 | 说明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUN() | 返回某列值之和 |
4.4.1 AVG() 函数
#计算产品表中所有产品的平均价格
SELECT AVG(prod_price) as avg_price from products;
#计算特定供应商所提*品的平均价格
SELECT AVG(prod_price) as avg_price
from products
WHERE vend_id = 1003;
注意:AVG()函数忽略列值为 null 的行
4.4.2 count() 函数
- COUNT() 确定表中行的数目或符合特定条件的行的数目
- 使用COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。
- 使用COUNT(column)对特定列中具有值的行进行计数,忽略NULL值。