第8章 用通配符进行过滤
8.1 LIKE通配符
8.1.1 %通配符
SELECT pro_id, pro_name FROM prducts WHERE pro_name LIKE 'jet%'; //找出以jet开头的所有产品 SELECT pro_id, pro_name FROM prducts WHERE pro_name LIKE '%anvil%'; //名字中任何位置包含文本anvil的所有产品 SELECT pro_name FROM prducts WHERE pro_name LIKE 'a%e'; //以s开头,e结尾的所有产品 %可以是0个或多个字符 //%不会匹配NULL值的
8.1.2 下划线(_)通配符
SELECT pro_id, pro_name FROM prducts WHERE pro_name LIKE '_ton anvil'; //_只能匹配一个字符
8.2 使用通配符技巧
把通配符置于搜索模式的开始处,搜索起来是最慢的。不要过度使用
第9章 用正则表达式进行搜索
9.1 正则表达式介绍
9.2 使用MySQL正则表达式
9.2.1 基本字符匹配
SELECT pro_name FROM prducts WHERE pro_name REGEXP '1000' ORDER BY prod_name; //检索名字中包含1000的所有行,REGEXP代替了LIKE,表示其后面的用正则表达式处理 SELECT pro_name FROM prducts WHERE pro_name REGEXP '.000' ORDER BY prod_name; //.是特殊字符,表示匹配任意一个字符 //1000,2000都可以匹配上
LIKE会匹配整个列,如果被匹配的出现,那么LIKE不会找到它,相应行不会被返回,除非用通配符,而REGEXP是在列值内匹配,会找到被匹配的项,并返回找到的项。REGEXP使用^和$就和LIKE一样了。
9.2.2 进行OR匹配
SELECT pro_name FROM prducts WHERE pro_name REGEXP '1000|2000' ORDER BY prod_name; //搜索两个字符串之一
9.2.3 匹配几个字符之一
SELECT pro_name FROM prducts WHERE pro_name REGEXP '[123] Ton'//[1|2|3]也可以 ORDER BY prod_name; //匹配1 Ton或2 Ton或3 Ton。因此1 Ton和2 Ton都匹配(无3) SELECT pro_name FROM prducts WHERE pro_name REGEXP '1|2|3 Ton' ORDER BY prod_name; //系统认为是1或2或3 Ton 因此1000也会匹配成功 //[^123]表示除这些字符意外的任何东西
9.2.4 匹配范围
SELECT pro_name FROM prducts WHERE pro_name REGEXP '[1-5] Ton' ORDER BY prod_name; //[1-5]表示匹配1到5都可以 比如[a-z]
9.2.5 匹配特殊字符
SELECT pro_name FROM prducts WHERE pro_name REGEXP '\\.' ORDER BY prod_name; //转义字符用两个\\ //\\f 换页 \\n 换行 \\r 回车 \\t 制表 \\v 纵向制表
9.2.6 匹配字符类
9.2.7 匹配多个实例
SELECT pro_name FROM prducts WHERE pro_name REGEXP '\\([0-9] sticks?\\)' ORDER BY prod_name; //两个转义,使得()被匹配了, //[0-9]表示任意数字,sticks?匹配stick和sticks,因为?匹配它前面的任何字符的0次或1次出现 本例是s SELECT pro_name FROM prducts WHERE pro_name REGEXP '[[:digit:]]{4}' ORDER BY prod_name; //[:digit:]匹配任意数字,而{4}表示前面的字符出现4次 //所有两个连在一起表示匹配连在一起的任意4个数字。 WHERE pro_name REGEXP '[0-9][0-9][0-9][0-9]'//自然也是可以的
9.2.8 定位符
^ 文本的开始
$ 文本的结尾
[[:<:]] 词的开始
[[:>:]] 词的结尾
//想找一个数(包括以小数点开始的数,如.9) [0-9\\.]是不行的 //因为要匹配开头,[0-9\\.]直接从文本中找了 SELECT pro_name FROM prducts WHERE pro_name REGEXP '^[0-9\\.]' ORDER BY prod_name; //^匹配串的开始
LIKE匹配整个串而REGEXP匹配子串。利用定位符,通过用^开始每个表达式,用$结束每个表达式,可以使REGEXP的作用与LIKE一样。
第10章 创建计算字段
10.1 计算字段
字段(field) 基本上与列(column)的意思相同,经常互换使用,不过数据库列一般称为列,而术语字段通常用在计算字段的连接上。
10.2 拼接字段
SELECT Concat(vend_name, ' (', vend_country, ')') FROM vendors ORDER BY vend_name; //当vend_name是abv,vend_country是CN时 查出来显示的是abv (CN) 中间带着一个空格 //Concat() 是拼接串 SELECT Concat(RTrim(vend_name), ' (', RTrim(vend_country), ')') FROM vendors ORDER BY vend_name; //RTrim()会去掉右边所有空格 ' ('里面的没去掉 去掉的是括号括起来的 //LTrim()去掉左边空格 Trim()去掉两边空格
使用别名
SELECT Concat(RTrim(vend_name), ' (', RTrim(vend_country), ')') AS AA FROM vendors ORDER BY vend_name; //查出来的列显示是AA
10.3 执行算术计算
SELECT prod_id,quantity,item_price FROM orderitems WHERE order_nam = 20005; // 检索订单号20005的所有物品 SELECT prod_id, quantity, item_price, quantity*item_price AS expanded_price //进行了乘法计算 FROM orderitems WHERE order_nam = 20005;
第11章 使用数据处理函数
11.1 函数 Trim()就是一个去掉空格的函数
11.2 使用函数
11.2.1 文本处理函数
Upper(vend_name)可以将括号内的vend_name列所有文本转换成大写
常用的文本处理函数
Left() 返回串左边的字符 Length() 返回串的长度 Locate() 找出串的一个子串 Lower() 将串转换为小写 LTrim() 去掉串左边的空格 Right() 返回串右边的字符 RTrim() 去掉串右边的空格 Soundex() 返回串的SOUNDEX值 //SOUNDEX是一个将任何文本串转换为描述其语音表示的字母数字模式的算法。 SubString() 返回子串的字符 Upper() 将串转换为大写
11.2.2 日期和时间处理函数
AddDate() 增加一个日期(天、周等) AddTime() 增加一个时间(时、分等) CurDate() 返回当前日期 CurTime() 返回当前时间 Date() 返回日期时间的日期部分 DateDiff() 计算两个日期之差 Date_Add() 高度灵活的日期运算函数 Date_Format() 返回一个格式化的日期或时间串 Day() 返回一个日期的天数部分 DayOfWeek() 对于一个日期,返回对应的星期几 Hour() 返回一个时间的小时部分 Minute() 返回一个时间的分钟部分 Month() 返回一个日期的月份部分 Now() 返回当前日期和时间 Second() 返回一个时间的秒部分 Time() 返回一个日期时间的时间部分 Year() 返回一个日期的年份部分 //日期必须为格式yyyy-mm-dd SELECT cust_id, order_num FROM orders WHERE order_data = '2005-09-01'; //只能完全匹配这个日期,这个日期加更具体时间时,不能匹配 SELECT cust_id, order_num FROM orders WHERE Data(order_data) = '2005-09-01'; //Data()会比较是否含有这个日期,后面的小时分不管 SELECT cust_id, order_num FROM orders WHERE Data(order_data) BETWEEN '2005-09-01' AND '2005-09-30'; SELECT cust_id, order_num FROM orders WHERE Year(order_data) = 2005 AND Month(order_data) = 9; //上面两段是一个意思
11.2.3 数值处理函数
Abs() 返回一个数的绝对值 Cos() 返回一个角度的余弦 Exp() 返回一个数的指数值 Mod() 返回除操作的余数 Pi() 返回圆周率 Rand() 返回一个随机数 Sin() 返回一个角度的正弦 Sqrt() 返回一个数的平方根 Tan() 返回一个角度的正切
第12章 汇总数据
12.1 聚集函数
AVG() 返回某列的平均值 COUNT() 返回某列的行数 MAX() 返回某列的最大值 MIN() 返回某列的最小值 SUM() 返回某列值之和
12.1.1 AVG()函数
只适用于单个列
12.1.2 COUNT()函数
使用COUNT(*)对表中行的数目进行计数,不管表列中包含的是空值(NULL)还是非空值。
使用COUNT(column)对特定列中具有值的行进行计数,忽略NULL值。
12.1.3 MAX()函数
MAX()函数忽略列值为NULL的行。
12.1.4 MIN()函数
MIN()函数忽略列值为NULL的行。
12.1.5 SUM()函数
SUM()函数忽略列值为NULL的行。
12.2 聚集不同值
SELECT AVG(DISTINCT pro_price) AS avg_price FROM products WHER vend_id = 1003; //这样计算的平均值只考虑不同的价格
12.3 组合聚集函数
SELECT COUNT(*) AS num_items MIN(prod_price) AS price_min, Max(prod_price) AS price_max, AVG(prod_price) AS price_avg, FROM products; //返回了产品的数目,最高,最低,平均价格,4列
聚集函数用来汇总数据。MySQL支持一系列聚集函数,可以用多种方法使用它们以返回所需的结果。这些函数是高效设计的,它们返回结果一般比你在自己的客户机应用程序中计算要快得多。
第13章 分组数据
主要是GROUP BY和HAVING字句
13.1 数据分组
13.2 创建分组
SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id; //一共两列,对id排序并进行分组数据,也就是说,并不是对整个id表都计算一次num_prods
1.GROUP BY子句可以包含任意数目的列。这使得能对分组进行嵌套,为数据分组提供更细致的控制。
2.如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。换句话说,在建立分组时,指定的所有列都一起计算(所以不能从个别的列取回数据)。
3.GROUP BY子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数)。如果在SELECT中使用表达式,则必须在GROUP BY子句中指定相同的表达式。不能使用别名。
4.除聚集计算语句外,SELECT语句中的每个列都必须在GROUP BY子句中给出。
5.如果分组列中具有NULL值,则NULL将作为一个分组返回。如果列中有多行NULL值,它们将分为一组。
6.GROUP BY子句必须出现在WHERE子句之后,ORDER BY子句之前。
13.3 过滤分组
为WHERE过滤指定的是行而不是分组。事实上,WHERE没有分组的概念。
因此分组用HAVING。HAVING非常类似于WHERE。事实上,目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代。唯一的差别是WHERE过滤行,而HAVING过滤分组。
SELECT cust_id, COUNT(*) AS orders FROM orders GROUP BY cust_id; HAVING COUNT(*) >=2; //HAVING子句,它过滤COUNT(*) >=2(两个以上的订单)的那些分组。
这里有另一种理解方法,WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤。这是一个重
要的区别,WHERE排除的行不包括在分组中。这可能会改变计算值,从而影响HAVING子句中基于这些值过滤掉的分组。
SELECT vend_id,COUNT(*) AS num_prods FROM products WHERE pro_price >= 10 GROUP BY vend_id HAVING COUNT(*) >= 2; //列出了具有两个及以上的,价格为10以上的产品的供应商id
这条语句中,第一行是使用了聚集函数的基本SELECT,它与前面的例子很相像。WHERE子句过滤所有prod_price至少为10的行。然后按vend_id分组数据,HAVING子句过滤计数为2或2以上的分组。
13.4 分组和排序
SELECT order_num, SUM(quantity*item_price) AS ordertotal FROM orderitems GROUP BY order_num HAVING SUM(quantity*item_price) >=50; //检索总计订单价格大于等于50的订单的单号和总计订单价格
13.5 SELECT字句顺序
子 句 说 明 是否必须使用 SELECT 要返回的列或表达式 是 FROM 从中检索数据的表 仅在从表选择数据时使用 WHERE 行级过滤 否 GROUP BY 分组说明 仅在按组计算聚集时使用 HAVING 组级过滤 否 ORDER BY 输出排序顺序 否 LIMIT 要检索的行数 否