贺胖娇的编程之旅......

mysql必知必会学习笔记-2-检索数据

2019.04.03

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自己解释一个,正则表达式库解释另一个)。

发表评论