MySQL 速查
数据检索
SELECT 列1,列2,列3,FROM 表
SELECT * FROM 表
检索所有列SELECT DISTINCE 列 FROM 表
不显示重复数据SELECT 列 FROM 表 LIMIT 5
只显示前五行LIMIT 5,6
从行 5 开始的 6 行. 第一个数是位置,第二个数是行数- 数据库中第一行是 0 不是 1
- 完全限定的表名
排序检索数据
- 字句. 关键字 + 数据
ORDER BY 列
按照该列排序显示ORDER BY 列1, 列2
先按列 1 排序再按列 2 排序ORDER BY 列1,列2 DESC
降序排序,但只对 列 2 降序排序.只负责前面的一列- 多个列上降序排序,必须对梅格列都指定
DESC
关键字 ORDER BY
和LIMIT
组合,能够显示最高/低的值. 排列后,只显示第一个
过滤数据
SELECT 列1 FROM 表 WHERE 列=值;
搜索特定值的行WHERE
字句的操作符BETWEEN
在两个数值之间,<>或!=
不等于,其余与其他编程语言一样- MySQL 执行匹配不区分大小写,
WHERE = 'FUSES'
也可检索到Fuses
所在行 - 单引号限定特定字符串.数值与串类型进行比较,需要限定引号.与数值比较不需要引号
WHERE 列 BETWEEN 5 AND 10;
WHERE 列 IS NULL
空值检查
数据过滤
- 操作符,用来联结或改变
WHERE
子句中的子句的关键字.也称逻辑操作符 AND
,给WHERE
子句添加附加条件OR
,指示检索匹配任一条件的行(多条件满足一个就行)- 优先处理
AND
操作符,后处理OR
操作符 ()
可改变优先级顺序IN
指定条件范围WHERE 列 IN (值1,值2)
- 含义等于
WHERE 列 = 值1 OR 列 = 值2
- 含义等于
NOT
操作符 ,否定之后跟的任何条件,类似取反
用通配符进行过滤
LIKE
,使用通配符必须使用LIKE
操作符- 通配符:用来匹配值的一部分的特殊字符
- 搜索模式:由字面值\通配符或者两者组合构成的搜索条件
%
任何字符出现任意次数WHRER 列 LIKE 'jet%'
jet 开头的值%anvil%
任意包含%anvil%
的文本s%e
s 开头 e 结尾
_
只匹配单个字符- 通配符搜索处理比一般处理要慢
- 不要过度使用
- 尽量不要再搜索的最开始处使用(这样通配符搜索时,搜索范围就小了)
- 注意通配符的位置
正则表达式搜索
WHERE 列 REGEXP '1000'
包含文本 1000 的所有行REGEXP '正则表达式'
LIKE
匹配整个串(列),如果匹配的文本在列值中出现,LIKE
不会找到他,相应的行也不会被返回(除非使用通配符)- 通过
^ 和$
可以起到和LIKE
相同的作用
'1000|2000|3000'
表示匹配1000
或2000
或3000
[123]
匹配 1 或者 2 或者 3[0-9]
匹配一个范围\\.
匹配.
特殊字符需要用\\
转意- 字符类 P58 特定类型的集合,
[:alnum:]
任意字母和数字,等于[a-zA-Z0-9]
- 匹配多个实例
* + ?
匹配 0 个或多个 一个或者多个 0 个或 1 个{n}
指定数目的匹配{n,}
不少于指定数目的匹配{n,m}
匹配数目的范围(m 不超过 255)
- 定位符
^
文本 的开始- 也可以在集合中(
[和]
)用它来否定该集合
- 也可以在集合中(
$
文本的结尾[[:<:]]
词的开始[[:>:]]
词的结尾
创建计算字段
- 字段: 基本上与列(column)的意思相同,经常互换使用,不过数据库列一般称为列,而术语字段通常用在计算字段的连接上。
- 拼接(concatenate) 将值联结到一起构成单个值。
- 在 MySQL 的 SELECT 语句中,可使用 Concat()函数来拼接两个列。
- 多数 DBMS 使用 + 或 || 来实现拼接,MySQL 则使用 Concat()函数来实现。
SELECT Concat(name,'(',country,')')
- 上述显示结果 Anvils (USA)
- 过删除数据右侧多余的空格 RTrim()函数
SELECT Concat(Rtrim(name),'(',Rtrim(country),')')
- Anvils (USA)
- 别名(alias)是一个字段或值的替换名
- 别名用 AS 关键字赋予
SELECT Concat(Rtrim(name),'(',Rtrim(country),')') AS title
- 指示 SQL 创建一个包含指定计算的名为 title 的计算字段。
- 算术计算
+ - * /
加减乘除SELECT quantity*item_price AS expanded_price
SELECT Trim('abc')
数据处理函数
- 文本处理函数
- Upper()函数
SELECT vend_name, Upper(vend_name) AS vend_name_upcase
将文本转换为大写 - SOUNDEX 是一个将任何文本串转换为描述其语音表示的字母数字模式的算法。
- Upper()函数
函数 | 说明 |
---|---|
Left() | 返回串左边的字符 |
Length() | 返回串的长度 |
Locate() | 找出串的一个子串 |
Lower() | 将串转换为小写 |
LTrim() | 去掉串左边的空格 |
Right() | 返回串右边的字符 |
- 日期和时间处理函数
-
不管是插入或更新表值还是用 WHERE 子句进行过滤,日期必须为格式 yyyy-mm-dd
-
datetime。这种类型存储日期及时间值。
yyyy-mm-dd 00:00:00
-
Date(order_date)指示 MySQL 仅提取列的日期部分
SELECT cust_id ,order_num FROM orders WHERE Date(order_date) = `2005-09-01` -- 单行注释:可以防止因不知道具体时间而导致的匹配失败 # mysql中可以使用的单行注释 /* 多行注释 */
-
如果你想要的仅是日期,使用 Date()是一个良好的习惯
- 匹配某个月所有订单
SELECT cust_id,oder_num FROM orders WHERE Date(order_date) BETWEEN `2005-09-01` AND `2005-09-30`
-
WHERE Year(order_date)= 2005 AND Month(order_date) = 9
- 检索出 order_date 为 2005 年 9 月的所有行
-
函数 | 说明 |
---|---|
AddDate() | 增加一个日期(天、周等) |
AddTime() | 增加一个时间(时、分等) |
CurDate() | 返回当前日期 |
CurTime() | 返回当前时间 |
Date() | 返回日期时间的日期部分 |
DateDiff() | 计算两个日期之差 |
Date_Add() | 高度灵活的日期运算函数 |
Date_Format() | 返回一个格式化的日期或时间串 |
Day() | 返回一个日期的天数部分 |
DayOfWeek() | 对于一个日期,返回对应的星期几 |
Hour() | 返回一个时间的小时部分 |
Minute() | 返回一个时间的分钟部分 |
Month() | 返回一个日期的月份部分 |
Now() | 返回当前日期和时间 |
Second() | 返回一个时间的秒部分 |
Time() | 返回一个日期时间的时间部分 |
Year() | 返回一个日期的年份部分 |
-
数值处理函数
函数 说明 Abs() 返回一个数的绝对值 Cos() 返回一个角度的余弦 Exp() 返回一个数的指数值 Mod() 返回除操作的余数 Pi() 返回圆周率 Rand() 返回一个随机数 Sin() 返回一个角度的正弦 Sqrt() 返回一个数的平方根 Tan() 返回一个角度的正切
汇总数据
函数具体使用见 P 77
- 聚集函数 - 需要汇总数据而不用把它们实际检索出来
- 对表中数据(而不是实际数据本身)汇总
- 返回实际表数据是对时间和处理资源的一种浪费
函数 | 说明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之和 |
- 聚集不同值
函数(DISTINCT 列名)
忽略相同的数值 - 组合聚集函数
分组数据
GROUP BY
分组数据-
句可以包含任意数目的列。
-
在建立分组时,指定的所有列都一起计算
-
列出的每个列都必须是检索列或有效的表达式
-
如果分组列中具有 NULL 值,则 NULL 将作为一个分组返回。
-
GROUP BY 子句必须出现在 WHERE 子句之后,ORDER BY 子句之前
-
使用 WITH ROLLUP 关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值,
SELECT vend_id ,COUNT(*) AS num_prods FROM products GROUP BY vend_id WITH ROLLUP;
-
- 过滤分组
WHERE
过滤的是行,而不是分组HAVING
,过滤分组。 所有类型的WHERE
字句都可以用HAVING
代替
- 分组和排序
ORDER BY
和GROUP BY
的区别- 一般在使用 GROUP BY 子句时,应该也给出 ORDER BY 子句。这是保证数据正确排序的唯一方法。千万不要仅依赖 GROUP BY 排序数据。
- SELECT 子句顺序
使用子查询
同时获取两个表的内容
- 子查询(subquery),即嵌套在其他查询中的查询
对于 prod——id 为 TNT2 的所有订单物品,检索他的 order——num 列
SELECT order_num
FROM oderitems
WHRER prod_id = 'TNT2';
-- ----查询结果----
-- order_num --
-- ---------------
-- 200005 --
-- 200007 --
------------------
查询这些 order_num 的 cust_id
SELECT cust_id
FROM oders
WHERE order_nunm IN((200005,20007));
-- ----查询结果----
-- cust_id --
-- ---------------
-- 10001 --
-- 10004 --
------------------
关键字 IN ((20201228220400-x4e50b8 "Programming/MySQL/CrashCourse#数据过滤"))
把上述两个查询组合为一个查询
SELECT cust_id
FROM oders
WHERE oder_num(
SELECT order_num
FROM oderitems
WHERE prod_id + 'TNT2');
但改代码难以阅读和调试,所以应该有适当的缩进和换行。
- 作为计算字段使用子查询
- 使用了完全限定列名
SELECT cust_name,cust_state,(
SELECT COUNT(*)
FROM oders
WHERE orders.cust_id = customers.cust_id)AS orders
FROM customers
ORDER BY cust_name;
- 相关子查询 涉及外部查询的子查询。
orders.cust_id = customers.cust_id
联结表
- 关系表原因
- 重复信息既浪费时间又浪费存储空间
- 信息发生变化改动一次即可
- 如果有重复数据很难保证每次输入该数据的方式都相同
- 各表通过某些常用的值(即关系设计中的关系(relational))互相关联
- 外键(foreign key) 外键为某个表中的一列,它包含另一个表的主键值,定义了两个表之间的关系。
- 可伸缩性(scale) 能够适应不断增加的工作量而不失败。设计良好的数据库或应用程序称之为可伸缩性好(scale well)。
- 联结 结是一种机制,用来在一条 SELECT 语句中关联表,因此称之为联结
- 创建联结,规定要联结的所有表以及它们如何关联
- 指定的列在不同表中
- WHERE 语句正确联结
SELECT 列1, 列2 ,列3
FROM 表1 ,表2
WHERE 表1.id = 表2.id
ORDER BY 列1 , 列2;
-
笛卡儿积
- 由没有联结条件的表关系返回的结果为笛卡儿积。所以
WHERE
语句很重要 - 检索出的行的数目将是第一个表中的行数乘以第二个表中的行数。
- 叉联结
- 由没有联结条件的表关系返回的结果为笛卡儿积。所以
-
内部联结
- 等值联结也成为内部链接
- 两个表之间的关系是 FROM 子句的组成部分,以 INNER JOIN 指定。
- 传递给 ON 的实际条件与传递给 WHERE 的相同。
SELECT vend_name,prod_name,prod_price FROM endors INNER JOIN products ON vendors.vend_id = products.vend_id;
-
联结多个表
SELECT prod_name, vend_name,prod_price,quantity FROM orderitems,products,vendors WHERE products.vend_id = vendors.vend_id AND oderitems.prod_id = products.prod_id AND order_num =20005
创建高级联结
-
表别名,只能查询中使用
[[CrashCourse#字段]]别名
AS
FROM customers AS c ,orders AS o, orderitems AS oi
-
其他三种联结
-
自联结
-
自然联结
-
外部联结
- OUTER JOIN
在使用 OUTER JOIN 语法时,必须使用 RIGHT 或 LEFT 关键字指定括其所有行的表(RIGHT 指出的是 OUTER JOIN 右边的表,而 LEFT 指出的是 OUTER JOIN 左边的表)。
即从左边表拥有的行中,去挑出符合条件的行(右边的表可能范围小于左边表)
-
-
使用带聚集函数的联结[[#汇总数据]]
-
使用联结和联结条件
组合查询
UNION
将多个SELECT
语句的结果组合成单个结果集- 使用情形
- 在单个查询中从不同的表返回类似结构的数据
- 对单个表执行多个查询,按单个查询返回数据
- 给出每条
SELECT
语句,在各条语句之间放上关键字UNION
- UNION 规则
- 由两条或两条以上的 SELECT 语句组成
- UNION 中的每个查询必须包含相同的列、表达式或聚集函数
- 列数据类型必须兼容
- 包含或取消重复的行
- UNION 从查询结果集中自动去除了重复的行
- 如果想返回所有匹配行,可使用 UNION ALL 而不是 UNION
- 对组合查询结果排序
- 只能使用一条 ORDER BY 子句,必须出现在最后一条 SELECT 语句之后
全文本搜索
支持全文本搜索的特定数据库类型:"创建和操纵表"
"用通配符进行过滤"
,"正则表达式搜索"
的限制
- 性能
- 需要明确控制
- 没有智能化结果
使用方法
- 启用
- 创建表时接受 FULLTEXT 子句
CREATE TABLE t1(... FULLTEXT(note_text) )
- note_text 代表列
- 不要在导入数据时使用 FULLTEXT
- 创建表时接受 FULLTEXT 子句
- 必须索引被搜索的列,而且要随着数据的改变不断地重新索引
- 索引之后,SELECT 可与 Match()和 Against()一起使用以实际执行
- Match() 指定被搜索的列,其值必须与 FULLTEXT()中定义的相同
- Against() 指定要使用搜索的表达式
- 除非使用 BINARY 方式(本章中没有介绍),否则全文本搜索不区分大小写。
- 全文搜索可以直接对搜索结果排序,优先返回具有较高等级的行
查询拓展
放宽所返回的全文本搜索结果的范围。
- 进行一个基本的全文本搜索
- 检查这些匹配行并选择所有有用的词
- 再次进行全文本搜索,这次不仅使用原来的条件,而且还使用所有有用的词
SELECT ....
WHERE Match(note_text) Against(`anvils` WITH QUERY EXPANSION)
布尔文本搜索
- 要匹配的词;
- 要排斥的词(如果某行包含这个词,则不返回该行,即使它包含其他指定的词也是如此);
- 排列提示(指定某些词比其他词更重要,更重要的词等级更高);
- 表达式分组;
- 另外一些内容
该搜索方式在 FULLTEXT
索引的情况下也可以使用. 是一种非常缓慢的操作.
需要指定布尔操作符,否则结果与默认搜索方式结果一致
# 匹配包含heavy但不包含任意以rope开始的词的行
SELECT ....
WHERE Match(note_text) Against(`heavy -rope*` IN BOOLEAN MODE)
布尔操作符
布尔操作符 | 说明 |
---|---|
+ | 包含 |
- | 排除 |
> | 包含,且增加等级值 |
< | 包含,且减少等级值 |
() | 把词组成子表达式 |
~ | 取消一个词的排序值 |
* | 词尾的通配符 |
"" | 定义一个短语 |
注意
- 短词被忽略且从索引中排除,(3 个或 3 个以下字符的词)
- 如果一个词出现在 50% 以上,则将它作为一个非用词忽略。(Boolean 模式除外)
- 表中的行数少于 3 行,则全文本搜索不返回结果
- 忽略词中的单引号。don't 索引为 dont。
- 不具有词分隔符(包括日语和汉语)的语言不能恰当地返回全文本搜索结果。
- 仅在 MyISAM 数据库引擎中支持全文本搜索。
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于