MySQL必知必会第十一章-
使用数据处理函数
大多数SQL支持以下类型的函数:
1> 文本函数:用于处理文本串(删除或填充值,转换值为大写或小写)
2> 数值函数:用于在数值数据上进行算术操作(返回绝对值,进行代数运算)
3> 日期和时间函数:用于处理日期和时间值并从这些值中提取特定成分(返回两个日期之差,检查日期的有效性)
4> 系统函数:返回DBMS正使用的特殊信息(如返回用户登陆信息,检查版本细节)
1.文本处理函数
SELECT vend_name,Upper(vend_name) AS vend_name_upcase FROM vendors ORDER BY vend_name; #Upper()将文本转换为大写
常见的的文本处理函数
函数 | 说明 |
---|---|
Left() | 返回串左边的字符 |
Length() | 返回串的长度 |
Locate() | 找出串的一个字串 |
Lower() | 将串转换为小写 |
LTrim() | 去掉串左边的空格 |
RTrim() | 去掉串右边的空格 |
Right() | 返回串右边的字符 |
Soundex() | 返回串的SOUNDEX值 |
Upper() | 将串转换为大写 |
SOUNDEX是一个将任何文本串转换为描述其语音表示的字母数字模式的算法。SOUNDEX考虑了类似的发音字符和音节,使得能对串进行发音比较而不是字母比较。
SELECT cust_name , cust_contact FROM customers WHERE cust_contact = 'Y. Lie'; #联系名实际上是Y. Lie,但是cust_contact中写成了‘Y. Lee’,那么现在无法查找到该联系名
SELECT cust_name, cust_contact FROM customers WHERE Soundex(cust_contact) = Soundex('Y. Lee'); #,WHERE子句使用Soundex()函数来转换cust_contact列值和搜索串为它们的SOUNDEX值。因为Y.Lee和Y.Lie发音相似,所以它们的SOUNDEX值匹配
2.日期和时间处理函数
常见的日期和时间处理函数
函数 | 说明 |
---|---|
AddDate() | 增加一个日期(天、周等) |
AddTime() | 增加一个时间(时、分等) |
CurDate() | 返回当前日期 |
CurTime() | 返回当前时间 |
Date() | 返回日期时间的日期部分 |
DateDiff() | 计算两个日期之差 |
Date_Add() | 高度灵活的日期运算函数 |
Date_Format() | 返回一个格式化的日期或时间串 |
Day() | 返回一个日期的天数部分 |
DayOfWeek() | 对于一个日期,返回对应的星期几 |
Hour() | 返回一个时间的小时部分 |
Minute() | 返回一个时间的分钟部分 |
Month() | 返回一个日期的月份部分 |
Now() | 返回当前日期和时间 |
Second() | 返回一个时间的秒部分 |
Time() | 返回一个日期时间的时间部分 |
Year() | 返回一个日期的年份部分 |
MySQL使用的日期格式必须为格式yyyy-mm-dd。2005年9月1日,给出为2005-09-01。
SELECT cust_id, order_num FROM orders WHERE order_date = '2005-09-01'; #检索订单日期为2005-09-01的订单记录。
如果用当前日期和时间存储订单日期(存储的order_date 值为2005-09-01 11:30:05),则WHERE order_date = '2005-09-01'失败。即使给出具有该日期的一行,也不会把它检索出来,因为WHERE匹配失败。解决办法是指示MySQL仅将给出的日期与列中的日期部分进行比较,而不是将给出的日期与整个列值进行比较。为此,必须使用Date()函数。Date(order_date)指示MySQL仅提取列的日期部分:
SELECT order_num,cust_id FROM orders WHERE Date(order_date) = '2005-09-01';
当然,也存在一个Time()函数,在你只想要时间时应该使用它。
SELECT cust_id, order_num FROM orders WHERE Year(order_date) = 2005 AND Month(order_date) = 9; #检索2005年9月的所有订单
还有一种方法:
SELECT cust_id, order_num FROM orders WHERE order_date BETWEEN '2005-09-01' AND '2005-09-30';
3.数值处理函数
常用的数值处理函数:
函数 | 说明 |
---|---|
Abs() | 返回一个数的绝对值 |
Cos() | 返回一个角度的余弦 |
Exp() | 返回一个数的指数值 |
Mod() | 返回除操作的余数 |
Pi() | 返回圆周率 |
Rand() | 返回一个随机数 |
Sin() | 返回一个角度的正弦 |
Sqrt() | 返回一个数的平方根 |
Tan() | 返回一个角度的正切 |
汇总数据
当需要对数据进行汇总而不是检索表中数据时,MySQL提供了专门的函数。这种例子有以下几种:
1> 确定表中行数(或者满足某个条件或包含某个特定值的行数)
2> 获得表中行组的和
3> 找出表列(或所有行或某些特定的行)的最大值、最小值和平均值
聚集函数(aggregate function),运行在行组上,计算和返回单个值的函数。
函数 | 说明 |
---|---|
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之和 |
1.AVG()函数
AVG()通过对表中行数计数并计算特定列值之和,求得该列的平均值。AVG()可用来返回所有列的平均值,也可以用来返回特定列或行的平均值。
SELECT AVG(prod_price) AS avg_prcie FROM products; #返回表中所有产品的平均价格
SELECT AVG(prod_price) AS avg_price FROM products WHERE prod_id = 1003; #返回特定列的平均值
只用于单个列 AVG()只能用来确定特定数值列的平均值,而且列名必须作为函数参数给出。为了获得多个列的平均值,必须使用多个AVG()函数。AVG()函数忽略列值为NULL的行。
2.COUNT()函数
COUNT()函数进行计数。可利用COUNT()确定表中行的数目或符合特定条件的行的数目。
COUNT()函数有两种使用方式:
1> 使用COUNT(*)对表中行的数目进行计数,包含NULL在内
2> 使用COUNT(column)对特定列中具有值的行进行计数,不包含NULL值
SELECT COUNT(*) AS num_cust FROM customers; #这里COUNT对所有行计数
SELECT COUNT(cust_email) AS num_cust FROM customers; #这里COUTN对cust_email)中有值的行进行计数
3.MAX()函数
MAX()返回指定列中的最大值。MAX()要求指定列名
SELECT MAX(prod_price) AS max_price FROM products; #返回products中最贵的物品的价格
对非数值数据使用MAX() 虽然MAX()一般用来找出最大的数值或日期值,但MySQL允许将它用来返回任意列中的最大值,包括返回文本列中的最大值。在用于文本数据时,如果数据按相应的列排序,则MAX()返回最后一行。MAX()函数忽略列值为NULL的行。
4.MIN()函数
MIN()的功能正好与MAX()功能相反,它返回指定列的最小值。与MAX()一样,MIN()要求指定列名。
SELECT MIN(prod_price) AS min_price FROM products; #MIN()返回products表中最便宜物品的价格。
5.SUM()函数
SUM()用来返回指定列值的和(总计)。
```SELECT SUM(quantity) AS items_orderd
FROM orderitems
WHERE order_num = 20005;
SUM()也可以用来合计计算值。
SELECT SUM(quantity*item_price) AS total_price FROM orderitems WHERE order_num = 20005;
利用标准的算术操作符,所有聚集函数都可用来执行多个列上的计算。
5.DISTINCT聚集不同值
以上5个聚集函数都可以如下使用:
1> 对所有的行执行计算,指定ALL参数或不给参数(因为ALL是默认
行为);
2> 只包含不同的值,指定DISTINCT参数。
SELECT AVG(DISTINCT prod_price) AS avg_price FROM products WHERE vend_id = 1003;
DISTINCT必须使用列名,不能用于计算或表达式。
6.组合聚集函数
实际上SELECT语句可根据需要包含多个聚集函数:
SELECT COUNT(*) AS num_items, MIN(prod_price) AS min_price, MAX(prod_price) AS max_price, AVG(prod_price) AS price_avg FROM products; #注意这里的多个聚集函数之间必须用逗号隔开,否则会报错
分组数据
1.创建分组
分组是在SELECT语句的GROUP BY子句中建立的:
SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id; #。GROUP BY子句指示MySQL按vend_id排序并分组数据。
使用WITH ROLLUP关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值:
SELECT vend_id, COUNT(*) AS num_prods FROM products GROUP BY vend_id WITH ROLLUP;
2.过滤分组
MySQL为此目的提供了另外的子
句,那就是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 prod_price >= 10 GROUP BY vend_id HAVING COUNT(*) >= 2;
SELECT vend_id,COUNT(*) AS num_prods FROM products GROUP BY vend_id HAVING COUNT(*) >= 2;
3.分组和排序
GROUP BY和ORDER BY的区别:
ORDER BY | GROUP BY |
---|---|
排序产生的输出 | 分组行。但输出可能不是分组的顺序 |
任意列都可以使用(甚至非选择的列也可以使用) | 只可能使用选择列或表达式列,而且必须使用每个选择列表达式 |
不一定需要 | 如果与聚集函数一起使用列(或表达式),则必须使用 |
SELECT order_num, SUM(quantity*item_price) AS ordertotal FROM orderitems GROUP BY order_num HAVING SUM(quantity*item_price) >= 50;
SELECT order_num, SUM(quantity*item_price) AS ordertotal FROM orderitems GROUP BY order_num HAVING SUM(quantity*item_price) >= 50 ORDER BY ordertotal;
4.SELECT 子句顺序
SELECT语句中子句的顺序:
子句 | 说明 |
---|---|
SELECT | 要返回的列或表达式 |
FROM | 从中检索数据的表 |
WHERE | 行级过滤 |
GROUP BY | 分组说明 |
HAVING | 组级过滤 |
ORDER BY | 输出排序顺序 |
LIMIT | 要检索的行数 |
使用子查询
1.利用子查询进行过滤
假如需要列出订购物品TNT2的所有客户,应该怎样检索?
(1) 检索包含物品TNT2的所有订单的编号。
(2) 检索具有前一步骤列出的订单编号的所有客户的ID。
(3) 检索前一步骤返回的所有客户ID的客户信息。
上述每个步骤都可以单独作为一个查询来执行。
SELECT order_num FROM orderitems WHERE prod_id = 'TNT2'; #,对于prod_id为TNT2的所有订单物品,它检索其order_num列
SELECT cust_id FROM orders WHERE order_num IN (20005,20007); #查询具有订单20005和20007的客户ID
对于上面的两个单独的查询,可以把一条SELECT语句返回的结果用于另一条SELECT语句的WHERE子句。
SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = 'TNT2');
现在得到了订购物品TNT2的所有客户的ID。下一步是检索这些客户ID的客户信息。
SELECT cust_name, cust_contact FROM customers WHERE cust_id IN (10001,10004);
可以把其中的WHERE子句转换为子查询而不是硬编码这些客户id。
SELECT cust_name, cust_contact FROM customers WHERE cust_id IN (SELECT cust_id FROM orders WHERE order_num IN (SELECT order_num FROM orderitems WHERE prod_id = 'TNT2'));
把子查询分解为多行并且适当地进行缩进,能极大地简化子查询的使用。
2. 作为计算字段使用子查询
假如需要显示customers表中每个客户的订单总数。订单与相应的客户ID存储在orders表中。
为了执行这个操作,遵循下面的步骤。
(1) 从customers表中检索客户列表。
(2) 对于检索出的每个客户,统计其在orders表中的订单数目。
SELECT cust_id, COUNT(order_num) AS num FROM orders GROUP BY cust_id;
可使用SELECT COUNT(*)对表中的行进行计数,并且通过提供一条WHERE子句来过滤某个特定的客户ID,可仅对该客户的订单进行计数。
SELECT COUNT(*) FROM orders WHERE cust_id = 10001; #对客户10001的订单进行计数
为了对每个客户执行COUNT()计算,应该将COUNT()作为一个子查询。
SELECT cust_name, cust_state, (SELECT COUNT(*) FROM orders WHERE orders.cust_id = customers.cust_id) AS orders FROM customers ORDER BY cust_name;
相关子查询(correlated subquery) 涉及外部查询的子查询。任何时候只要列名可能有多义性,就必须使用这种语法(表名和列名由一个句点分隔)。
联接表
1.创建联结
联结的创建非常简单,规定要联结的所有表以及它们如何关联即可。
SELECT vend_name, prod_name,prod_price FROM vendors, products WHERE vendors.vend_id = products.vend_id ORDER BY vend_name,prod_name;
2.内部联结
目前为止所用的联结称为等值联结(equijoin),它基于两个表之间的相等测试。这种联结也称为内部联结。其实,对于这种联结可以使用稍微不同的语法来明确指定联结的类型。下面的SELECT语句返回与前面例子完全相同的数据:
SELECT vend_name, prod_name,prod_price FROM vendors INNER JOIN products ON vendors.vend_id = products.vend_id;
这里,两个表之间的关系是FROM子句的组成部分,以INNERJOIN指定。在使用这种语法时,联结条件用特定的ON子句而不是WHERE子句给出。传递给ON的实际条件与传递给WHERE的相同。
3.联结多个表
SQL对一条SELECT语句中可以联结的表的数目没有限制。创建联结的基本规则也相同。首先列出所有表,然后定义表之间的关系。
SELECT vend_name,prod_name, prod_price,quantity FROM orderitems,vendors, products WHERE products.vend_id = vendors.vend_id AND orderitems.prod_id = products.prod_id AND order_num = 20005; #此例子显示编号为20005的订单中的物品。
返回订购产品TNT2的客户列表:
```SELECT cust_id, cust_name,cust_contact,prod_id
FROM orderitems,orders,customers
WHERE customers.cust_id = orders.cust_id
AND
MySQL必知必会第十一章-的更多相关文章
- MySQL必知必会1-20章读书笔记
MySQL备忘 目录 目录 使用MySQL 检索数据 排序检索数据 过滤数据 数据过滤 用通配符进行过滤 用正则表达式进行搜索 创建计算字段 使用数据处理函数 数值处理函数 汇总数据 分组数据 使用子 ...
- mysql必知必会
春节放假没事,找了本电子书mysql必知必会敲了下.用的工具是有道笔记的markdown文档类型. 下面是根据大纲已经敲完的章节,可复制到有道笔记的查看,更美观. # 第一章 了解SQL## 什么是S ...
- mysql学习--mysql必知必会1
例如以下为mysql必知必会第九章開始: 正則表達式用于匹配特殊的字符集合.mysql通过where子句对正則表達式提供初步的支持. keywordregexp用来表示后面跟的东西作为正則表達式 ...
- 《MySQL必知必会》整理
目录 第1章 了解数据库 1.1 数据库基础 1.1.1 什么是数据库 1.1.2 表 1.1.3 列和数据类型 1.1.4 行 1.1.5 主键 1.2 什么是SQL 第2章 MySQL简介 2.1 ...
- 读《MySql必知必会》笔记
MySql必知必会 2017-12-21 意义:记录个人不注意的,或不明确的,或不知道的细节方法技巧,此书250页 登陆: mysql -u root-p -h myserver -P 9999 SH ...
- 读《MySQL必知必会》我学到了什么?
前言 最近在写项目的时候发现自己的SQL基本功有些薄弱,遂上知乎查询MYSQL关键字,期望得到某些高赞答案的指点,于是乎发现了 https://www.zhihu.com/question/34840 ...
- 《MySQL必知必会》学习笔记——前言
前言 MySQL已经成为世界上最受欢迎的数据库管理系统之一.无论是用在小型开发项目上,还是用来构建那些声名显赫的网站,MySQL都证明了自己是个稳定.可靠.快速.可信的系统,足以胜任任何数据存储业务的 ...
- 《MySQL必知必会》通配符 ( like , % , _ ,)
<MySQL必知必会>通配符 ( like , % , _ ,) 关键字 LIke WHERE 搜索子句中使用通配符,必须使用 LIKE 操作符. % 百分号通配符 % 表示任意字符出现任 ...
- 《MySQL必知必会》过滤数据,数据过滤(where ,in ,null ,not)
<MySQL必知必会>过滤数据,数据过滤 1.过滤数据 1.1 使用 where 子句 在SEL ECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤. WHERE子句在表名(FR ...
- MySQL必知必会复习笔记(1)
MySQL必知必会笔记(一) MySQL必知必会是一本很优秀的MySQL教程书,并且相当精简,在日常中甚至能当成一本工作手册来查看.本系列笔记记录的是:1.自己记得不够牢的代码:2.自己觉得很重要的代 ...
随机推荐
- tp5.0中使用PHPexcel,以及Loader的一些问题
在5.0中使用PHPexcel遇到一些问题,记录一下方便以后查看. 非使用PHPexcel的方法: 参考:http://blog.csdn.net/sinat_35861727/article/det ...
- Docker install GitLab
示范一下如何透过Docker安装GitLab,也顺便将一些常用的东西纪录一下 作业系统: CentOS 7 安装Docker CE 1. 先移除系统上预先安装的Docker旧版本 yum remove ...
- 利用Django实现webUI展示
1.说明 最近老大想要做一个webUI界面,为了展示我们数据中心工作内容,需要把各自的工作内容用webUI展示出来.目前我负责的做公司名称归一化的问题. 2.Django实现web 具体实现是完全按照 ...
- Linux:PCBSD系统的安装
这期继续更新有关Linux系统的安装步骤以及使用,感兴趣的可以来看下!!! 安装PCBSD系统 系统映像文件下载 PCBSD 9.2官方正式版:http://www.veryhuo.com/down/ ...
- 安装oracle11g client 【INS-30131】执行安装程序验证所需的初始设置失败的解决方法
今天在服务器(操作系统windows server 2008R2)上安装Oracle11g 客户端,弹出“执行安装程序验证所需的初始设置失败”,如上图.网上找了一些方法,简单整理如下,仅供参考. 问题 ...
- go语言关于线程与通道channal
在go语言中,封装了多线程的使用方法,使其变得简单易用. 在这里说说自己一点体会,不正确的地方还是请各位大牛指正. 关于go语言的并发机制,这很简单,在你要执行的函数前面加上go即可 比如: pack ...
- Centos7_64环境搭建
smb搭建参考 https://www.cnblogs.com/areyouready/p/10369917.html activeMq搭建参考 https://blog.csdn.net/u0122 ...
- JAVA字符串的常见处理和操作
1.纯数字字符串补0为指定位,格式化输出(例如00482这样) 使用String.format处理: int mNumber = 1; // 0 代表前面补充0 // 4 代表长度为4 // d 代表 ...
- jcifs windows 域账户单点登录(转)
1.首先从http://jcifs.samba.org 这个站点下载 jcifs-1.3.2.jar包. 2.把这个包放到相应的lib文件下面. 3.对web.xml文件进行配置,添加如下内容 < ...
- linux防火墙设置常用命令
1.永久性生效,重启后不会复原 开启: chkconfig iptables on 关闭: chkconfig iptables off 2.即时生效,重启后复原 开启: service iptabl ...