整体的SQL学习笔记,之后再分开来详细写。
查询 SELECT
Select查询某些属性列的语法
SELECT column, another_column, ...
FROM mytable;
Select查询所有列
SELECT *
FROM mytable;
条件查询
条件查询语法
SELECT column, another_column, ...
FROM mytable
WHERE condition
AND/OR another_condition
AND/OR ...;
Operator | Condition | SQL Example |
---|---|---|
=,!=,<,<=,>,>= | Standard numerical operators | Col_name != 4 |
BETWEEN ... AND ... | Number is within range of two values | Col_name BETWEEN 1.5 AND 10.5 |
NOT BETWEEN ... AND ... | Number is not within range of two values | Col_name NOT BETWEEN 1 AND 10 |
IN(...) | Number exists in a list | Col_name IN (2,4,6) |
NOT IN(...) | Number does not exist in a list | Col_name NOT IN(1,3,5) |
字符串操作符
Operator | Condition | Example |
---|---|---|
= | Case sensitive exact string comparison | Col_name = "abc" |
!= or <> | Case sensitive exact string inequality comparison | Col_name != "abcd" |
LIKE | Case insensitive exact string comparison | Col_name LIKE "ABC" |
NOT LIKE | Case insensitive exact string inequality comparison | Col_name NOT LIKE "ABCD" |
% | Used anywhere in a string to match a sequence of zero or more characters(only with LIKE or NOT LIKE) | Col_name LIKE "%AT%"(matches "AT", "ATTIC","CAT" or even "BATS") |
_ | Used anywhere in a string to match a single character(only with LIKE or NOT LIKE) | Col_name LIKE "AN_"(matches "AND", but not "AN") |
IN(...) | String exists in a list | Col_name IN ("A", "B", "C") |
NOT IN(...) | String does not exist in a list | Col_name NOT IN("D", "E", "F") |
查询结果过滤Filtering和排序Sorting
选出唯一结果的语法
SELECT DISTINCT column, another_column, ...
FROM mytable
WHERE condition(s);
结果排序
SELECT column, another_column, ...
FROM mytable
WHERE condition(s)
ORDER BY column ASC/DESC;
通过LIMIT选取部分结果
SELECT column, another_column, ...
FROM mytable
WHERE condition(s)
ORDER BY column ASC/DESC
LIMIT num_limit OFFSET num_offset;
用JOINs进行多表联合查询
用INNER JOIN连接表的语法
SELECT column, another_table_column, ...
FROM mytable
INNER JOIN another_table
ON mytable.id = another_table.id
WHERE condition(s)
ORDER BY column, ... ASC/DESC
LIMIT num_limit OFFSET num_offset;
INNER JOIN可以想成两个集合的交集。
外连接OUTER JOINs
用LEFT/RIGHT/FULL JOIN做多表查询
SELECT column, another_column, ...
FROM mytable
INNER/LEFT/RIGHT/FULL JOIN another_table
ON mytable.id = another_table.matching_id
WHERE condition(s)
ORDER BY column, ... ASC/DESC
LIMIT num_limit OFFSET num_offset;
LEFT JOIN
RIGHT JOIN
FULL JOIN
在查询中使用表达式
包含表达式的例子
SELECT particle_speed / 2 AS half_particle_speed
FROM physics_data
WHERE ABS(particle_position) * 10 > 500;
在查询中进行统计
对全部结果数据做统计
SELECT AGG_FUNC(column_or_expression) AS aggregate_description, ...
FROM mytable
WHERE constraint_expression;
常见统计函数
Function | Description |
---|---|
COUNT(*), COUNT(column) | 计数,统计非NULL的行数 |
MIN(column) | 最小的一行 |
MAX(column) | 最大的一行 |
AVG(column) | 平均值 |
SUM(column) | 求和 |
MySQL支持的统计函数
Name | Description |
---|---|
AVG() |
Return the average value of the argument |
BIT_AND() |
Return bitwise AND |
BIT_OR() |
Return bitwise OR |
BIT_XOR() |
Return bitwise XOR |
COUNT() |
Return a count of the number of rows returned |
COUNT(DISTINCT) |
Return the count of a number of different values |
GROUP_CONCAT() |
Return a concatenated string |
MAX() |
Return the maximum value |
MIN() |
Return the minimum value |
STD() |
Return the population standard deviation 标准差 |
STDDEV() |
Return the population standard deviation |
STDDEV_POP() |
Return the population standard deviation |
STDDEV_SAMP() |
Return the sample standard deviation |
SUM() |
Return the sum |
VAR_POP() |
Return the population standard variance 标准方差 |
VAR_SAMP() |
Return the sample variance 样本方差 |
VARIANCE() |
Return the population standard variance 标准方差 |
用分组的方式统计
SELECT AGG_FUNC(column_or_expression) AS aggregate_description, ...
FROM mytable
WHERE constraint_expression
GROUP BY column;
用HAVING进行筛选
SELECT group_by_column, AGG_FUNC(column_or_expression) AS aggregate_result_a
FROM mytable
WHERE condition
GROUP BY column
HAVING group_condition;
查询执行顺序
完整的SELECT查询
SELECT DISTINCT column, AGG_FUNC(column_or_expression), …
FROM mytable
JOIN another_table
ON mytable.column = another_table.column
WHERE constraint_expression
GROUP BY column
HAVING constraint_expression
ORDER BY column ASC/DESC
LIMIT count OFFSET COUNT;
执行顺序:
-
FROM 和 JOIN
确定一个数据源表(含临时表)
-
WHERE
按要求进行数据筛选,并丢弃不符合要求的数据行,AS别名还不能在这个阶段使用
-
GROUP BY
数据进行分组,统计
-
HAVING
如用了GROUP BY分组,HAVING会在分组完成后对结果集再次筛选,AS别名不能使用
-
SELECT
对结果col简单筛选或计算,决定输出什么数据
-
DISTINCT
如果数据行有重复,DISTINCT将负责排重
-
ORDER BY
结果集确定的情况下,对结果进行排序,可以用AS别名
-
LIMIT / OFFSET
截取部分数据
处理日期的函数
SQL中处理日期的函数
#date(日期)返回日期时间的日期部分:
DATE(col_name)
#year(年)返回日期时间的年份:
YEAR(col_name)
#time(时间)返回日期时间的时间:
TIME(col_name)
#month(月份)返回日期时间的月份:
MONTH(col_name)
#day of week(星期)返回对应的是星期几,适用于MySQL:
DAYOFWEEK(col_name)
#day(日)返回日期时间的天数:
DAY(col_name)
#hour(小时)返回日期时间的小时:
HOUR(col_name)
#minute(分钟)返回日期时间的分钟:
MINUTE(col_name)
#second(秒)返回日期时间的秒钟:
SECOND(col_name)
增减日期
#adddate(增加日期)增加或减少一个日期(年季月日时),这里有三种写法:
ADDDATE(date, INTERVAL value addunit);
DATE_ADD(date, INTERVAL value addunit);
ADDDATE(date, days)
常见的addunit可取值有:
- Year
- Quarter
- Month
- Day
- Week
- Hour
- Minute
- Second
- Millisecond
增减时间
ADDTIME(datetime, addtime)
当前时间
#curdate(当前日期)返回当前日期:
CURDATE()
#curtime(当前时间)返回当前时间:
CURTIME()
#now(现在)返回当前日期时间:
NOW()
其他日期相关函数
#datediff(日期区别)计算两个日期的差值:
DATEDIFF(date1, date2)
#dayofweek(星期中的哪一天)返回日期为星期几:
DAYOFWEEK(date)
#date_format(格式)返回一个格式化的日期时间:
DATE_FORMAT(date, format)
format(格式)可以取下表的值:
- %a:工作日缩写名称(星期日至星期六)
- %b:月份的缩写(1月至12月)
- %c:数字月份名称(0到12)
- %D:一个月的天,以数字值后跟后缀(第一,第二,第三,...)
- %d:月份中的天,以数值(01到31)
- %e:每月的天,以数值(0到31)
- %f:微秒(000000至999999)
- %H:小时(00到23)
- %h:小时(00到12)
- %I:小时(00到12)
- %i:分钟(00至59)
- %j:一年中的某天(001至366
- %k:小时(0到23)
- %l:小时(1到12)
- %M:月的全称(1月至12月)
- %m:月名称(作为数字值(00到12))
- %p:AM或PM
- %r:以12小时AM或PM格式显示的时间(hh:mm:ss AM / PM)
- %S:秒(00至59)
- %s:秒(00至59)
- %T:时间,以24小时格式(hh:mm:ss)
- %U:周,其中星期日是一周的第一天(00到53)
- %u :Week,其中星期一是一周的第一天(00到53)
- %V:周,其中星期日是一周的第一天(01到53)。与%X一起使用
- %v:周,其中星期一是一周的第一天(01到53)。与%x一起使用
- %W:工作日名称的完整名称(星期日至星期六)
- %w:星期几,星期天= 0,星期六= 6
- %X:星期的年份,其中星期日是一周的第一天。与%V一起使用
- %x:一周的第一年中的一周的年份。与%v一起使用
- %Y:年,为4位数字
- %y:年,为2位数字数值
常用对日期的筛选
#几个小时内的数据
DATE_SUB(NOW(), INTERVAL 5 HOUR)
#今天
select * from 表名 where to_days(时间字段名) = to_days(now());
#昨天
SELECT * FROM 表名 WHERE TO_DAYS( NOW( ) ) - TO_DAYS( 时间字段名) <= 1
#7天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 7 DAY) <= date(时间字段名)
#近30天
SELECT * FROM 表名 where DATE_SUB(CURDATE(), INTERVAL 30 DAY) <= date(时间字段名)
#本月
SELECT * FROM 表名 WHERE DATE_FORMAT( 时间字段名, '%Y%m' ) = DATE_FORMAT( CURDATE( ) , '%Y%m' )
#上一月
SELECT * FROM 表名 WHERE PERIOD_DIFF( date_format( now( ) , '%Y%m' ) , date_format( 时间字段名, '%Y%m' ) ) =1
#查询本季度的数据
SELECT * FROM order WHERE QUARTER(时间字段名)=QUARTER(NOW())
#查询上季度的数据
SELECT * FROM order WHERE QUARTER(时间字段名)=QUARTER(DATE_SUB(NOW(),INTERVAL 1 QUARTER))
#查询当年(今年)的数据
SELECT * FROM `order` WHERE YEAR(order_time)=YEAR(NOW())
#查询去年的数据
SELECT * FROM `order` WHERE YEAR(order_time)=YEAR(DATE_SUB(NOW(),INTERVAL 1 YEAR))
文本处理函数
大小写转换
#upper(大写)将string(串)转换为大写:
UPPER('string')
#lower(小写)将string(串)转换为小写:
LOWER('string')
字符串拼接
CONCAT(col_name, col_name)
#加入别的字符需要使用引号
文本数据的选择
#Left(左)返回串左边选定多少的字符串:
LEFT(string, number)
#Right(右)返回串右边选定多少的字符串:
RIGHT(string, number)
#Length(长度)返回串的字节长度:
LENGTH(string)
#Char_length返回串的汉字字符长度:
CHAR_LENGTH(string)
定位
LOCATE(substring, string, start)
#其中,substring为只想要检索的子串,string是原文本,start是位置(数字),留意空格也是算一个位置的。
修剪
#Ltrim(左,修剪)去掉串左边的空格:
LTRIM('string')
#Rtrim(右,修剪)去掉串右边的空格:
RTRIM('string')
#Substring(子,串)返回子串的字符:
SUBSTRING(string, start, length)
数值处理函数
常用数值处理函数
#abs(absolute value, 绝对值)可以返回一个数的绝对值:
ABS(col_name)
#mod(余数), 返回除之后的余数,这里有三种写法:
MOD(x,y)
x MOD y
x % y
#其中,x为被除数,y为除数
#rand(random, 随机),返回一个随机数:
RAND()
#或者可以设定一个可以重现的”种子(seed)“:
RAND(seed)
#sqrt(平方根)返回一个数的平方根:
SQRT(col_name)
#这里数值必须大于0
聚集函数
#avg(average, 平均数),计算特定列值的平均数。
AVG(col_name)
#count(计数), 确定表中行的数目或符合特定条件的行的数目。
COUNT(*)
#对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。
COUNT(column)
#对特定列中具有值的行进行计数,忽略 NULL值。
#max(最大)返回指定列中的最大值。
MAX(column)
#min(最小)返回指定列中的最小值。
MIN(column)
#sum(总计)用来返回指定列值的和
SUM(column)
组合与联结
UNION
可以将多条SELECT语句的结果组合成单个结果集。
适用UNION的两种基本情况:
- 在单个查询中从不同的表返回类似结构的数据;
- 对单个表执行多个查询,按单个查询返回数据
SELECT A.姓名, B.薪资
FROM 职员 AS A
LEFT JOIN 薪水 AS B
USING (职位编号)
UNION
SELECT A.姓名, B.薪资
FROM 职员 AS A
RIGHT JOIN 薪水 AS B
USING (职位编号)
UNION将去除重复数据行;UNION ALL 为全集合,包括重复行。
文本检索和编辑
LIKE & REGEXP
LIKE匹配整个列,而REGEXP匹配的是列值。
如果被匹配的文本在列值中出现:
- LIKE将不会找到它,相应的行也不被返回(除非使用通配符)。
- REGEXP将会找到它,相应的行将被返回
WHERE col_name REGEXP 'value'
MySQL中的正则表达式匹配(自版本 3.23.4后)不区分大小写,即大写和小写被视作一样。为区分大小写,可使用BINARY关键字。
同时对多个串进行匹配
可以用OR(或者),即为符号“|”
WHERE col_name REGEXP 'value_1|value_2|value_3'
可以适用方括号([])来简化匹配
WHERE col_name REGEXP '[value1value2value3]value'
例:
SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000|2000|3000'
ORDER BY prod_name
# 可以写为:
SELECT prod_name AS 利用方括号偷懒
FROM products
WHERE prod_name REGEXP '[123]000'
ORDER BY prod_name
否定匹配
“^”在字符集合中表示否定。
[123]匹配数字1、2和3,但是[^123]匹配所有除了1、2和3的任何东西。
集合匹配
可以使用集合或字符类来匹配。
类 | 说明 |
---|---|
[:alnum:] | 任意字母和数字,同[a-zA-z0-9] |
[:alpha:] | 任意字符,同[a-zA-Z] |
[:blank:] | 空格和制表符,同[\\t] |
[:cntrl:] | ASCII控制字符 |
[:digit:] | 任意数字,同[0-9] |
[:lower:] | 任意小写字母,同[a-z] |
[:print:] | 任意可打印字符 |
[:punct:] | 既不在[:alnum:]又不在[:cntrl:]中的任意字符 |
[:space:] | 包括空格在内的任意空白字符,同[\\f\\n\\r\\t\\v] |
[:upper:] | 任意大写字母,同[A-Z] |
[:xdigit:] | 任意十六进制数字,同[a-fA-F0-9] |
转义字符与元字符
双反斜杠“\“来对特殊字符进行转义(escaping)。
空白元字符
元字符 | 说明 |
---|---|
\\f | 换页 |
\\n | 换行 |
\\r | 回车 |
\\t | 制表 |
\\v | 纵向制表 |
重复元字符
元字符 | 说明 |
---|---|
* | 0个或多个匹配 |
+ | 1个或多个匹配 |
? | 0个或1个匹配 |
{n} | 指定数目的匹配 |
{n,} | 不少于指定数目的匹配 |
{n,m} | 匹配数目的范围 |
定位符
元字符 | 说明 |
---|---|
^ | 文本的开始 |
$ | 文本的结尾 |
[[:<:]] | 词的开始 |
[[:>:]] | 词的结尾 |
全文本搜索
聚集索引与非聚集索引
正文内容本身就是一种按照一定规则排列的目录便是聚集索引。
目录纯粹是目录,正文纯粹是正文的排序方式便是非聚集索引。
开启索引
启用全文本搜索的方式非常简单,通过FULLTEXT(全文本)子句便可在create table中直接对列进行索引:
CREATE TABLE 表名(列1 INT, 列2 CHAR(100), 列3 TEXT, FULLTEXT(列3))
扩展查询
在使用查询扩展时,MySQL对数据和索引进行两遍扫描来完成搜索:
- 进行一个基本的全文本搜索,找出与搜索条件匹配的所有行;
- MySQL检查这些匹配行并选择所有有用的词;
- MySQL再次进行全文本搜索,这次不仅使用原来的条件,并且还使用所有有用的词。
WHERE MATCH(列名) AGAINST('想要搜索的文本' WITH QUERY EXPANSION)
布尔模式
利用布尔模式,我们不必定义FULL TEXT索引即可使用全文本搜索,并且可以直接根据且不限于如下的细节来锁定内容:
- 要匹配的词;
- 要排斥的词(如果某行包含这个词,则不返回该行,即使它包含其他指定的词);
- 排列提示(指定某些词比其他词更重要,更重要的词等级更高);
- 表达式分组。
WHERE MATCH(列名) AGAINST('想要搜索的文本' IN BOOLEAN MODE)
布尔操作符 | 说明 |
---|---|
+ | 包含,词必须存在 |
- | 排除,词必须不出现 |
> | 包含,而且增加等级值 |
< | 包含,且减少等级值 |
() | 把词组成子表达式 |
~ | 取消一个词的排序值 |
* | 词尾的通配符 |
"" | 定义一个短语 |
插入数据INSERT
INSERT(插入)是用来插入/添加行到数据库表的。利用INSERT我们可以插入如下数:
- 完整的行;
- 行的一部分;
- 多个不同的行;
- 查询/计算的结果。
普通INSERT
INSERT INTO 职员
VALUE (1, '张三', 1638264, 2);
更为安全的做法是在INSERT INTO中定义信息的次序:
INSERT INTO 职员(编号, 姓名, 电话, 职位编号)
VALUE (1, '张三', 1638264, 2);
INSERT的降级,low priority:
#原本的INSERT语句:
INSERT INTO TABLE 表 VALUE(值1, 值2,值3, ...)
#降级INSERT的运行顺序:
INSERT LOW_PRIORITY INTO TABLE 表 VALUE(值1, 值2,值3, ...)
更新UPDATE与删除DELETE
UPDATE
基本的UPDATE语句由三部分构成:
- 待更新的表;
- 待更新的列名和新的值;
- 更新的过滤条件。
UPDATE 表名
SET 列名1 = '新的值1', #注意若是更新多个列的时候,这里需要要用逗号隔开。
列名2 = '新的值2'
WHERE 条件
DELETE
DELETE FROM 表名
WHERE 条件
表的操作
删除表
DROP TABLE 表名;
重命名表
RENAME TABLE 表一 TO 表名;
NULL值限定
在建立表的过程中,其实我们可以强制性规定指定列是否可以允许出现NULL值:
CREATE TABLE 例子
(列名一 字符属性 NOT NULL,
列名二 字符属性 NULL);
主外键
主键值必须唯一,表中的每个行必须具有唯一的主键值。
如果主键使用单个列,则它的值必须唯一。如果使用多个列,则这些列的组合值必须唯一。
PRIMARY KEY(列名一, 列名二, ...)
外键:
FOREIGN KEY (列名一) REFERENCES 表名二(列名二)
自动增量
AUTO_INCREMENT告诉MySQL,本列每当增加一行时自动增量。
列名 字符属性 NOT NULL AUTO_INCREMENT
想要找到最后一个AUTO_INCREMENT的值,可以使用如下代码:
SELECT LAST_insert_ID()
指定默认
如果在插入行时没有给出值,MySQL允许指定此时使用的默认值。DEFAULT关键字指定:
列名 字符属性 NOT NULL DEFAULT 数值
更新表定义
为更新表定义,可使用ALTER TABLE语句。
例子:
CREATE TABLE 订单
(订单号 int NOT NULL AUTO_INCREMENT,
顾客ID int NOT NULL,
PRIMARY KEY(订单号));
INSERT INTO 订单(顾客ID)
VALUES(1),(8),(13),(6),(24),(54);
ALTER TABLE 订单
ADD 商品数量 INT NOT NULL DEFAULT 1
视图
视图的作用
包含了SQL查询的视图可以:
反复重用SQL语句;
简化复杂的SQL操作;
使用表的组成部分而不是整个表;
保护数据:
- 可以给用户授予表的特定部分的访问权限而不是整个表的访问权限;
更改数据格式和表示:
- 视图可返回与底层表的表示和格式不同的数据。
视图的常见规则
- 视图的命名必须唯一,不得与别的视图或是表相同;
- 创建视图的数量没有限制,但必须有相对应的访问权限;
- 视图可以互相嵌套;
- ORDER BY可以用在视图中,但若是使用视图时也使用了ORDER BY,那视图中的ORDER BY将会被覆盖;
- 视图不可索引;
- 视图可以与表同时使用。
视图创建
创建视图:
CREATE VIEW 视图名称
查看创建视图:
SHOW CREATE VIEW 视图名称
删除视频:
DROP VIEW 视图名称
更新/覆盖视图:
CREATE OR REPLACE VIEW 视图名称
存储过程
把流程分门别类地建立起一个模版,不但会大幅便捷我们的操作,统一我们的代码以保证数据的一致性,还可以简化对变动的管理。这就是存储过程。
存储过程的执行
CALL 过程名称(参数);
创建存储过程
DELIMITER // #使用“//”作为新的语句结束分隔符
CREATE PROCEDURE 过程名称(参数)
BEGIN #(开始)
储存内容条件语句;
END// #(结束)
DELIMITER ; #恢复为原来的语句分隔符“;”
删除存储过程
DROP PROCEDURE 过程名称;
#注意,此处不需要参数的括号。
参数
MySQL支持三种类型的参数:
- IN(传递给存储过程);
- OUT(从存储过程传出);
- INOUT(对存储过程传入和传出)。