鉴于毕业之后大概率去当 CURD 程序员的需要,本计划应运而生。但是我目前写 SQL 的水平仅仅停留在基础的增删改查阶段,甚至比较复杂的多表查询都不熟练,显然无法胜任该岗位。为了提高 SQL 水平,从今天开始,我将主要围绕 《MySQL 必知必会》、《SQL 进阶教程》、《高性能 MySQL》展开学习,开启“高性能 SQL”计划。
Part I. SQL 基础入门
1.了解数据库和表
SHOW DATABASES; #显示所有的数据库
SHOW TABLES; #显示正在使用的数据库中所有的表
SHOW COLUMNS FROM customers;#显示表的列的信息,包含字段名、数据类型、默认值等信息
DESCRIBE customers;#与上一条功能相同
SHOW STATUS;#显示服务器状态
SHOW CREATE DATABASE stu_info;#显示创建数据库的SQL语句
SHOW CREATE TABLE stu;#显示创建表的SQL语句
SHOW GRANTS;#显示授予用户的安全权限
SHOW ERRORS;#显示错误信息
SHOW WARNINGS;#显示警告信息
2.SELECT 语句
SELECT prod_name
FROM products;#检索单列
SELECT prod_id, prod_name, prod_price
FROM products;#检索多列
SELECT * from products;#检索所有列。一般来说,除非你确实需要表中的每个列,否则最好别使用*通配符
SELECT DISTINCT vend_id
FROM products;#使用DISTINCT关键字来实现结果去重
SELECT prod_name
FROM products
LIMIT 5,5;#使用LIMIT关键字来限制结果。表示返回五个结果(从第一行开始)。
SELECT prod_name
FROM products
LIMIT 5,5;#表示返回从第五行开始的五行结果。
SELECT prod_name
FROM products
LIMIT 5 OFFSET 5;#与上一语句功能相同,使用OFFSET关键字增强可读性。
3.排序检索数据
SELECT prod_name
FROM products
ORDER BY prod_name;#对检索出的结果按照prod_name字母顺序排序
SELECT prod_id, prod_price, prod_name
FROM products
ORDER BY prod_price, prod_name;#先按照prod_price进行排序,价格相同的项再按照prod_name排序
SELECT prod_id, prod_price, prod_name
FROM products
ORDER BY prod_price DESC;#使用DESC关键字进行降序排序。进行升序的关键字是ASC,MySQL默认使用升序。
SELECT prod_id, prod_price, prod_name
FROM products
ORDER BY prod_price DESC, prod_name;#DESC关键字只作用于其前面的一列。该语句prod_price为降序,prod_name为升序
4.过滤数据
注意:WHERE 子句应该在 ORDER BY 子句之后。
SELECT prod_name,prod_price
FROM products
WHERE prod_price = 2.50;#例子
#WHERE子句中的操作符基本与平时使用的基本一致,但有三个值得注意的点
#1.MySQL中的不等于既可以使用 <> ,也可以使用 !=。
#2.MySQL对于varchar类型的字段默认不区分大小写。
#3.进行值比较时,如果将值与串类型(varchar类型)的列比较时要使用引号,与数值列进行比较时则不需要引号。
SELECT prod_name, prod_price
FROM products
WHERE prod_price BETWEEN 5 AND 10; //范围值检查
SELECT prod_name
FROM products
WHERE prod_price IS NULL;//空值检查
以上介绍了WHERE子句的基本用法,接下来是其进阶的组合用法。
#1.AND 逻辑操作符
SELECT prod_id, prod_price, prod_name
FROM products
WHERE vend_id = 1003 AND prod_price <= 10;
#2.OR 逻辑操作符
SELECT prod_name, prod_price
FROM products
WHERE vend_id = 1002 OR vend_id = 1003;
#注意:AND 和 OR 操作符存在优先级的问题,AND 的优先级高于 OR,可以通过括号来改变优先级。
#“任何时候使用具有AND和OR操作符的WHERE子句,都应该使用圆括号明确地分组操作符。不要过分依赖默认计算次序,即使它确实是你想要的东西也是如此。”
#3.IN 操作符
SELECT prod_name, prod_price
FROM products
WHERE vend_id IN (1002,1003)
ORDER BY prod_name;
#使用 IN 操作符实际上完成了与 OR 相同的功能。但是使用 IN 操作符书写简单、逻辑清晰而且速度快。
#4.NOT 操作符
SELECT prod_name, prod_price
FROM products
WHERE vend_id NOT IN (1002,1003)
ORDER BY prod_name;
5.使用通配符进行过滤
MySQL 中主要是使用 LIKE 操作符进行通配操作,LIKE指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。
首先是几个名词的解释:
- 通配符(wildcard): 用来匹配值的一部分的特殊字符。
- “搜索模式(search pattern): 由字面值、通配符或两者组合构成的搜索条件。
- 谓词(predicate): 返回值为真值(true/false/unknown)的函数。从技术上说,LIKE是谓词而不是操作符。
#1.百分号通配符
# % 表示任何字符出现任意次数,包括0次
SELECT prod_id, prod_name
FROM products
WHERE prod_name LIKE 'jet%';#找出所有以jet起头的产品
# % 可以有很多种使用方式,如'%anvil%'、's%e'等。
#注意:即使是WHERE prod_name LIKE '%'也不能匹配用值NULL作为产品名的行。
#2.下划线通配符
# _ 表示任意字符出现一次,并且只能是一次
SELECT prod_id, prod_name
FROM products
WHERE prod_name LIKE '_ ton anvil';
使用通配符的注意事项:
- 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符;
- 在确实需要使用通配符时,除非绝对有必要,否则不要把它们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的;
- 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。
6.使用正则表达式进行搜索
#1.基本字符匹配
SELECT prod_name
FROM products
WHERE prod_name REGEXP '.000'
ORDER BY prod_name;#使用REGEXP关键字匹配,匹配以任意字符开头以000结尾的产品名称
#注意:使用正则表达式匹配默认是不区分大小写的,可以在 REGEXP 后面添加 BINARY 关键字区分大小写
#2.OR 匹配
“SELECT prod_name
FROM products
WHERE prod_name REGEXP '1000|2000'
ORDER BY prod_name;#匹配产品名包含1000或2000的产品
#注意:使用正则表达式的匹配不是整列匹配,而且包含即可
#3.范围匹配
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[1-5] Ton'
ORDER BY prod_name;
#4.特殊匹配
SELECT vend_name
FROM vendors
WHERE vend_name REGEXP '\\.'
ORDER BY vend_name; #转义字符:\\
#5.匹配字符类
#[:alnum:] 任意字母和数字(同[a-zA-Z0-9])
#[:alpha:] 任意字符(同[a-zA-Z])
#[:blank:] 空格和制表(同[\\t])
#[:cntrl:] ASCII控制字符(ASCII 0到31和127)
#[:digit:] 任意数字(同[0-9])
#[:graph:] 与[:print:]相同,但不包括空格
#[:lower:] 任意小写字母(同[a-z])
#[:print:] 任意可打印字符
#[:punct:] 既不在[:alnum:]又不在[:cntrl:]中的任意字符
#[:space:] 包括空格在内的任意空白字符(同[\\f\\n\\r\\t\\v])
#[:upper:] 任意大写字母(同[A-Z])
#[:xdigit:] 任意十六进制数字(同[a-fA-F0-9])
#6.匹配多个实例
#* 0个或多个匹配
#+ 1个或多个匹配(等于{1,})
#? 0个或1个匹配(等于{0,1})
#{n} 指定数目的匹配
#{n,} 不少于指定数目的匹配
#{n,m} 匹配数目的范围(m不超过255)
SELECT prod_name
FROM products
WHERE prod_name REGEXP '[[:digit:]]{4}'
ORDER BY prod_name;
#7.定位符
#^ 文本的开始
#$ 文本的结尾
#[[: 词的开始
#[[:>:]] 词的结尾
SELECT prod_name
FROM products
WHERE prod_name REGEXP '^[0-9\\.]'
ORDER BY prod_name;
#注意:“LIKE和REGEXP的不同在于,LIKE匹配整个串而REGEXP匹配子串。利用定位符,通过用^开始每个表达式,用$结束每个表达式,可以使REGEXP的作用与LIKE一样。”
未完待续....