《MySQL必知必会》读书笔记(二) 8~14章

1、like

搜索模式:由字面值,通配符或两者组合构成的搜索条件。

like指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。

%表示任何字符出现任意次数:

select prod_id,prod_name from products where prod_name like 'jet%';

表示搜素prod_name以jet起头的词。

通配符可在搜索模式中任意位置使用,并且可以使用多次:

select prod_id,prod_name from products where prod_name like '%anvil%';

虽然%似乎可以匹配任何东西,但无法匹配NULL。即使是where prod_name like '%'也不能匹配用NULL作为产品名的行。

通配符“_”用法“%”相同,但只匹配单个字符:

SELECT prod_id,prod_name FROM products WHERE prod_name LIKE '_ ton avil';

2、使用通配符的技巧

通配符搜索的处理时间一般比较长,所以有一些技巧:


  • 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符;
  • 在确实需要使用通配符时,除非绝对有必要,否则不要把它们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。

3、使用正则表达式

SELECT prod_name FROM products WHERE prod_name REGEXP '1000' ORDER BY prod_name;

REGEXP在列值内进行匹配,如果被匹配的文本在列值中出现,相应的行将被返回。

MySQL中的正则表达式匹配不区分大小写,为区分大小写可使用BINARY关键字,如WHERE prod_name REGEXP  BINARY 'JetPack .000'

4、|为正则表达式的OR操作符:

SELECT prod_name FROM products WHERE prod_name REGEXP '1000|2000' ORDER BY prod_name;

5、匹配几个字符之一

WHERE prod_name REGEXP '[123] Ton'

相当于 ‘1 Ton|2 Ton|3 Ton’

而 '1|2|3 Ton' 不等于上述表达式,它表示匹配 1,2,3 Ton。

字符集合也可以被否定,它们将匹配除指定字符外的任何东西。为否定一个字符集,在集合的开始处放置一个^。[^123]匹配除123之外的任何东西。

6、匹配范围

[0123456789]可以写成[0-9]

7、匹配特殊字符

用\\为前导,.、|、[]、-、^需要如此匹配。

\\也可以用来引用元字符:


  • \\f    换页;
  • \\n    换行;
  • \\r    回车;
  • \\t    制表;
  • \\v    纵向制表。

为了匹配\本身,需要使用\\\。

多数正则表达式实现使用单个反斜杠转义特殊字符,但MySQL要求两个反斜杠。

8、字符类

字符类是预定义的字符集

  • [:alnum:]    任意字母和数字;
  • [:alpha:]    任意字符
  • [:blank:]    空格和制表符;
  • [:cntrl:]    ASCII控制字符 ASCII0到31和127;
  • [:digit:]    任意数字;
  • [:graph:]    任意可打印字符,但不包括空格;
  • [:lower:]    任意小写字母;
  • [:print:]    任意可打印字符;
  • [:punct:]    既不在[:alnum:]又不在[:cntrl:]中的任意字符;
  • [:space:]    包括空格在内的任意空白字符;
  • [:upper:]    任意大写字母;
  • [:xdigit:]    任意十六进制数字。

9、重复元字符

  • *    0个或多个匹配;
  • +    1个或多个匹配;
  • ?    0个或1个匹配;
  • {n}    指定数目的匹配;
  • {n,}    不少于指定数目的匹配;
  • {n,m}    匹配数目的范围m不超过255。

10、定位元字符

  • ^    文本的开始;
  • $    文本的结尾;
  • [[:<:]]    词的开始;
  • [[:>:]]    此的结尾。

^有两种用法,在集合中(用[和]定义)表示否定该集合;否则,用来指串的开始处。

简单的正则表达式测试,可以在不适用数据库表的情况下用SELECT来测试正则表达式,REGEXP检测总是返回0(没有匹配)或1(匹配):

SELECT 'hello' REGEXP '[0-9]';返回0。

11、拼接字段

SELECT语句中可适用Concat()函数拼接几个列:

SELECT Concat(vend_name, '(', vend_country, ')') FROM vendors ORDER BY vend_name;

不同于MySQL,多数DBMS使用+或||实现拼接。

12、Trim()函数去掉左右边的空格,LTrim()和RTrim()分别去掉左右边的空格。

13、用AS关键字给列赋予别名:

SELECT Concat(vend_name, '(', vend_country, ')') AS vend_title FROM vendors ORDER BY vend_name;

14、SELECT语句中可以对列执行算数运算:

SELECT prod_id, quantity, quantity * item_price AS expanded_price FROM orderitems;

15、使用SELECT Now() 利用Now()函数返回当前的日期和时间。

16、文本处理函数

  • Left()    返回串左边的字符;
  • Length()    返回串的长度;
  • Locate()    找出串的一个子串;
  • Lower()    将串转换为小写;
  • Right()    返回串右边的字符;
  • Soundex()    查找元音发音类似的;
  • SubString()    返回子串的字符;
  • Upper()    将串转换为大写。

17、日期和时间处理函数

  • AddDate()    增加一个日期;
  • AddTime()    增加一个时间;
  • CurDate()    返回当前日期;
  • CurTime()    返回当前时间;
  • Date()    返回日期时间的日期部分;
  • DateDiff()    计算两个日期之差;
  • Date_Add()    高度灵活的日期运算函数;
  • Date_Format()    返回一个格式化的日期或时间串;
  • Day()    返回一个日期的天数部分;
  • DayOfWeek() 对于一个日期,返回对应的星期几;
  • Hour()    返回一个时间的小时部分;
  • Minute()    返回一个时间的分钟部分;
  • Month()    返回一个日期的月份部分;
  • Now()    返回当前日期和时间;
  • Second()    返回一个时间的秒部分;
  • Time()    返回一个日期时间的时间部分;
  • Year()    返回一个日期的年份部分。

无论什么时候指定一个日期,不管是插入、更新还是用WHERE子句进行过滤,日期必须为yyyy-mm-dd格式。如果想要的仅仅是日期,则使用Date()函数,如果想要时间则使用Time()函数。

可以使用BETWEEN AND函数定义日志范围。

18、数值处理函数

  • Abs()    绝对值;
  • Cos()    角度的余弦;
  • Exp()    数的指数值;
  • Mod()    除的余数;
  • Pi()    圆周率;
  • Rand()    返回一个随机数;
  • Sin()   角度的正弦;
  • Sqrt()    数的平方根;
  • Tan()    角度的正切。

19、聚类函数

AVG()计算特定列的平均值,只能用来确定特定数值列的平均值,列名必须作为函数参数给出,为了获取多个列的平均值,必须使用多个AVG()函数。会忽略列值为NULL的行。

COUNT()函数,有两种用法:

  • COUNT(*)对表中行的数目进行计数,不论表列中包含的是空置还是非空值;
  • COUNT(column)对特定列中具有值的行进行计数,忽略NULL值。

MAX()函数,返回指定列中的最大值。一般用来找出最大的数值或日期值,但MySQL允许将它用来返回任意列中的最大值,包括文本列中的最大值。MAX()忽略列值为NULL的行。

MIN()函数的功能和MAX()相反。

SUM()函数返回指定列值的和,也可以用来合计计算值。

以上5个聚类函数都可以如下使用:

  • 对所有符合条件的行进行计算,指定ALL参数或不指定(默认行为);
  • 只包含不同的值,指定DISTINCT参数,如AVG(DISTINCT prod_price)。

20、分组数据 GROUP BY

SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id;

一些规定:

  • GROUP BY可以包含任意数目的列,按照多列合并后的值进行分组
  • GROUP BY子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚类函数)。如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式,不能使用别名;
  • 除聚类计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出;
  • 如果分组列中具有NULL值,则NULL将作为一个分组返回。
  • GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。

使用WITH ROLLUP关键字 查询的结果最后有一行统计的汇总结果,非统计列用NULL给出,如:

mysql> select name,sum(miles) as 'miles/driver'

    -> from driver_log group by name with rollup;

+-------+--------------+

| name  | miles/driver |

+-------+--------------+

| Ben   |          362 |

| Henry |          911 |

| Suzi  |          893 |

| NULL  |         2166 |

+-------+--------------+

4 rows in set (0.00 sec)

最后一行就是with rollup的输出。

用HAVING语句实现分组过滤,HAVING支持所有WHERE操作符,可以认为HAVING和WHERE执行方式都相同,只是一个针对行另一个针对行分组。

另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。

21、SELECT子句顺序(从前至后):

  1. SELECT
  2. FROM
  3. WHERE
  4. GROUP BY
  5. HAVING
  6. ORDER BY
  7. LIMIT

22、子查询

利用子查询进行过滤

SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = 'TNT2');

作为计算字段使用子查询

SELECT cust_name, cust_state, (SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name;



你可能感兴趣的:(MySQL入门)