select语句
-- 简单的查询
select prod_name from ta_name;
-- 查询几个列
select prod_id, prod_name from tb_name;
-- 查询所有列,一般不建议,检索不需要的列通常会降低检索和应用程序的性能
select * from tb_name;
-- 只返回不同的值
select distinct xxx_id from tb_name;
-- 返回前5行
select prod_name from tb_name limit 5;
-- 限制开始行和行数,例如从第3行开始,返回5行
select prod_name from tb_name limit 3,5;
-- 从Mysql5开始,从第3行返回5行可以写作:
select prod_mame from tb_name limit 5 OFFSET 3;
注意事项
(1)在原书中有这么一段话:
不能部分使用DISTINCT。DISTINCT关键字应用于所有列而 不仅是前置它的列。如果给出SELECT DISTINCT vend_id, prod_price,除非指定的两个列都不同,否则所有行都将被 检索出来
我自己建表试过,翻译一下就是,一般来说DISTINCT用于单列的去重,当用于多列的时候,当这两个列的值完全一样时会被去重,当其中一个值或者以上不同时,不会被去重。
(2)第一行是行0, limit 1,1实际上返回的是第2行数据。带一个值的返回的是第0行,也就是人眼看到的第一行的数据。
排序检索数据
关系数据库设计理论认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义。
示例:
-- order by子句
select prod_name from tb_name order by `id`;
-- 按多个列排序
select prod_name from tb_name order by `id`, `name`;
-- 降序
select prod_name from tb_name order by `id` DESC;
-- DESC关键字只应用到直接位于其前面的列名。
select prod_name from tb_name order by `id` DESC, name;
-- order by和limit组合
select prod_name from tb_name order by `price` DESC limit 1;
注意事项
(1)在字典(dictionary)排序顺序中,A被视为与a相同,这是MySQL(和大多数数据库管理系统)的默认行为。但是,许多数据库管理员能够在需要时改变这种行为(如果你的数据库包含大量外语字符,可能必须这样做)。 这里,关键的问题是,如果确实需要改变这种排序顺序,用简单的ORDER BY子句做不到。你必须请求数据库管理员的帮助。
(2)在给出ORDER BY子句时,应该保证它位于FROM子句之后。如果使用LIMIT,它必须位于ORDER BY之后。使用子句的次序不对将产生错误消息。
过滤数据
示例:
-- where查询
select prod_name from tb_name where `price`=3;
-- between and
select prod_name from tb_name where `price` between 3 and 10;
-- 空值检查
操作符
操作符 | 操作符说明 |
---|---|
= | 等于 |
<> | 不等于 |
!= | 不等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
BETWEEN | 在指定的两个值之间 |
注意事项
WHERE子句的位置 在同时使用ORDER BY和WHERE子句时,应该让ORDER BY位于WHERE之后,否则将会产生错误
使用不等于之类的判断请小心,例如price!=2,如果price的值为NULL,那么也是不会返回的,所以需要验证下是否需要值为NULL的行。
数据过滤
示例:
-- AND操作符
select prod_name from tb_name where t_name='test' and t_price=3;
-- OR操作符
select prod_name from tb_name where t_name='test' or t_name='test_1';
-- IN操作符
select prod_name from tb_name where t_name in('test', 'test_1');
-- NOT 操作符
select prod_name from tb_name where t_name NOT IN('test', 'test_1');
select * from department where revenue not between 6000 and 8000;
注意事项
(1)AND操作符的优先级高于OR操作符,但组合使用的时候一定要小心,一定用圆括号括起来避免产生歧义
(2)MySQL中的NOT: MySQL支持使用NOT对IN、BETWEEN和EXISTS子句取反,这与多数其他DBMS允许使用NOT对各种条件取反有很大的差别。
其他
(1)IN操作符和OR操作符功能相近,为什么使用IN操作符?
(1.1)在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
(1.2)在使用IN时,计算的次序更容易管理(因为使用的操作符更少)。
(1.3)IN操作符一般比OR操作符清单执行更快。
(1.4)IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句。
用通配符进行过滤
示例:
-- %通配符,%表示任何字符出现任意次数
select prod_name from tb_name where t_name like 'test%';
select prod_name from tb_name where t_name like '%test%';
-- _通配符,匹配一个字符
select prod_name from tb_name where t_name like '_est';
注意事项
(1)尾空格可能会干扰通配符匹配。
例如,在保存词 anvil 时,如果它后面有一个或多个空格,则子句WHERE prod_name LIKE ‘%anvil’将不会匹配它们,因为在最后的l后有多余的字符。
解决这个问题的一个简单的办法是在搜索模式最后附加一个%。
一个更好的办法是使用函数去掉首尾空格。
(2)虽然似乎%通配符可以匹配任何东西,但有一个例外,即NULL。
即使是WHERE prod_name LIKE ‘%‘也不能匹配用值NULL作为产品名的行。
(3)不要过度使用通配符。如果其他操作符能达到相同的目的,应该
使用其他操作符。
(4)在确实需要使用通配符时,除非绝对有必要,否则不要把它们用在搜索模式的开始处。
把通配符置于搜索模式的开始处,搜索起来是最慢的。
(5)仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据。
用正则表达式进行搜索
示例:
-- 基本字符匹配
select prod_name from tb_name where t_name REGEXP 'test';
select prod_name from tb_name where t_name REGEXP '.test';
select prod_name from tb_name where t_name REGEXP '*test';
-- 和Like相同的匹配
select prod_name from tb_name where t_name REGEXP '^test$';
-- OR匹配
select prod_name from tb_name where t_name REGEXP '1000|2000|3000';
select prod_name from tb_name where t_name REGEXP '[123] ton';
select prod_name from tb_name where t_name REGEXP '[^123] ton';
select prod_name from tb_name where t_name REGEXP '[1-5] ton';
-- 匹配特殊字符
select prod_name from tb_name where t_name REGEXP '\\-';
select prod_name from tb_name where t_name REGEXP '\\([0-9] sticks?\\)';
字符类
类 | 说明 |
---|---|
[: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]) |
重复元字符
元字符 | 说 明 |
---|---|
* | 0个或多个匹配 |
+ | 1个或多个匹配(等于{1,}) |
? | 0个或1个匹配(等于{0,1}) |
{n} | 指定数目的匹配 |
{n,} | 不少于指定数目的匹配 |
{n,m} | 匹配数目的范围(m不超过255) |
注意事项
(1)除非把字符|括在一个集合中,否则将会应用于整个串,例如'1|2|3 ton’匹配的是1或2或者'3 ton’,要想匹配 ‘[1|2|3] ton’匹配的是'1 ton’,‘2 ton’或'3 ton’
(2)多数正则表达式实现使用单个反斜杠转义特殊字符, 以便能使用这些字符本身。但MySQL要求两个反斜杠(MySQL自己解释一个,正则表达式库解释另一个)。