大多数SQL支持以下类型的函数:
1、用于处理文本串(如删除或填充值,转换值为大写或小写)的文本函数
2、用于在数值数据上进行算术操作(如返回绝对值,进行代数运算)的数值函数
3、用于处理日期和时间值并从这些值中提取特定成分的日期和时间函数
4、返回DBMS正使用的特殊信息(如返回用户登录信息,检查版本细节)的系统函数
SELECT语句及其条件表达式都可以使用这些函数。同时,INSERT 、UPDATE、DELECT语句及其条件表达式也可以使用这些函数。
UPPER(s) | 将字符串转换为大写 |
LOWER(s) | 将字符串 s 的所有字母变成小写字母 |
TRIM(s) | 去掉字符串 s 开始和结尾处的空格 |
SUBSTRING_INDEX(s, delimiter, number) | 返回从字符串 s 的第 number 个出现的分隔符 delimiter 之后的子串。如果 number 是正数,返回第 number 个字符左边的字符串。如果 number 是负数,返回第(number 的绝对值(从右边数))个字符右边的字符串。 |
SUBSTRING(s, start, length) | 从字符串 s 的 start 位置截取长度为 length 的子字符串 |
LENGTH(s) | 返回字符串s的字符数 |
例1:
mysql> SELECT platformName,Upper(platformName) AS new_data FROM roleinfo ORDER BY platformName;
+---------------+---------------+
| platformName | new_data |
+---------------+---------------+
| ainjigame_app | AINJIGAME_APP |
| cinjigame | CINJIGAME |
| xinjigame_app | XINJIGAME_APP |
+---------------+---------------+
mysql> SELECT SUBSTRING_INDEX('a*b','*',1) AS new_data;
+----------+
| new_data |
+----------+
| a |
+----------+
1 row in set (0.00 sec)
mysql> SELECT SUBSTRING_INDEX('a*b','*',-1)AS new_data;
+----------+
| new_data |
+----------+
| b |
mysql> SELECT SUBSTRING("RUNOOB", 2, 3) AS ExtractString;
+---------------+
| ExtractString |
+---------------+
| UNO |
+---------------+
mysql> SELECT platformName,LENGTH(platformName) AS new_data FROM roleinfo WHERE sex =0;
+--------------+----------+
| platformName | new_data |
+--------------+----------+
| cinjigame | 9 |
+--------------+----------+
AddDate() | 增加一个日期(天、周等) |
AddTime() | 增加一个时间(时、分等) |
CurDate() | 返回当前日期 |
CurTime() | 返回当前时间 |
Date() | 返回日期时间的日期部分 |
DateDiff() | 计算两个日期之差 |
DATE_FORMAT(d,f) | 按表达式f的要求显示日期d:返回一个格式化的日期或时间串 |
DAY(d) | 返回日期值d的天数部分 |
DAYOFWEEK(d) | 日期 d 今天是星期几:对于一个日期,返回对应的星期几 |
DAYOFYEAR(d) | 计算日期 d 是本年的第几天 |
HOUR(t) | 返回 t 中的小时部分 |
LOCALTIME() | 返回当前日期和时间 |
NOW() | 返回当前日期和时间 |
MINUTE(t) | 返回 t 中的分钟值 |
MONTHNAME(d) | 返回日期当中的月份名称,如 Janyary |
MONTH(d) | 返回日期d中的月份值,1 到 12 |
SECOND(t) | 返回 t 中的秒钟值 |
TIMEDIFF(time1, time2) | 计算时间差值 |
WEEK(d) | 计算日期 d 是本年的第几个星期,范围是 0 到 53 |
YEAR(d) | 返回一个日期的年份部分 |
TIME(d) | 返回一个日期时间的时间部分 |
数据经常需要用日期进行过滤。用日期进行过滤时需要注意一些别的问题和使用特殊函的MYSQL函数:
首先需要注意的是MYSQL使用的日期格式。无论你什么时候指定一个日期,不管是插入或更新表值还是使用WHERE子句进行过滤,日期格式必须为yyyy-mm-dd。虽然其他格式也行,但是这是首选格式,因为他排除了多义性。
例2:时间类型为int:时间戳
mysql> SELECT sex,createTime FROM roleinfo WHERE createTime = 1528216525;
+-----+------------+
| sex | createTime |
+-----+------------+
| 1 | 1528216525 |
+-----+------------+
例3:时间类型为date:日期
mysql> SELECT sex,logintime FROM roleinfo WHERE logintime = "2019-01-25";
+-----+------------+
| sex | logintime |
+-----+------------+
| 1 | 2019-01-25 |
+-----+------------+
例4:时间类型为timestamp:日期+时间
mysql> SELECT sex,changetime FROM roleinfo WHERE Date(changetime) = "2019-01-15";
+-----+---------------------+
| sex | changetime |
+-----+---------------------+
| 1 | 2019-01-15 22:40:22 |
+-----+---------------------+
例4_1:
mysql> SELECT career,changetime FROM roleinfo WHERE changetime <"2019-01-13 14:29:22" AND changetime >"2019-01-13 14:29:19";
+--------+---------------------+
| career | changetime |
+--------+---------------------+
| 2 | 2019-01-13 14:29:20 |
+--------+---------------------+
注:
例4中使用了Date()函数:指示MYSQL仅将给出的日期与列中值得日期部分进行比较,而不是将给出的日期与整个列值进行比较。当然也存在一个Time()函数用于值比较日期时间值中的时间部分
DATETIME类型用在你需要同时包含日期和时间信息的值时。MySQL检索并且以'YYYY-MM-DD HH:MM:SS'格式显示DATETIME值,支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。(“支持”意味着尽管更早的值可能工作,但不能保证他们可以。)
DATE类型用在你仅需要日期值时,没有时间部分。MySQL检索并且以'YYYY-MM-DD'格式显示DATE值,支持的范围是'1000-01-01'到'9999-12-31'。
TIMESTAMP列类型提供一种类型,你可以使用它自动地用当前的日期和时间标记INSERT或UPDATE的操作。
TIME数据类型表示一天中的时间。MySQL检索并且以"HH:MM:SS"格式显示TIME值。支持的范围是'00:00:00'到'23:59:59'。
工作中经常需要汇总数据而不是将它们全部检索出来(实际数据本身:返回实际数据是对时间和处理资源的浪费),这种类型的检索有以下特点:
①确定表中的行数(或者满足某个条件或包含某个特定值的行数)
②获得表中行组的和
③找出表列(或所有行或某些特定的行)的最大值、最小值和平均值
聚集函数(aggregate function):运行在行组上,计算和返回单个值的函数(MySQL还支持一些列的标准偏差聚集函数)
函数 | 说明 |
AVG() | 返回某列的平均值 |
COUNT() | 返回某列的行数 |
MAX() | 返回某列的最大值 |
MIN() | 返回某列的最小值 |
SUM() | 返回某列值之和 |
avg()通过对表中行数计数并计算特定列值之和,求得该列的平均值;avg()可用来返回所有列的平均值,也可用来返回特定列或行的平均值
例5:
mysql> SELECT AVG(level) AS avg_level FROM roleinfo;
+-----------+
| avg_level |
+-----------+
| 136.3333 |
+-----------+
注:此select语句返回值avg_level,它包含roleinfo表中所有角色的平均等级,roleinfo是一个别名
例5_1:
mysql> SELECT AVG(level) AS avg_level FROM roleinfo WHERE career = 2;
+-----------+
| avg_level |
+-----------+
| 104.0000 |
+-----------+
注:这条SQL语句包含了WHERE子语句,仅过滤出career为2的角色,avg_level中返回这些角色的等级的平均值
注:
1、avg()只能用来确定特定数值列的平均值,而且列名必须作为函数参数给出,为了获得多个列的平均值,必须使用多个avg()函数
2、avg()函数忽略列值为NULL的行
count()函数进行计数,可利用count()确定表中行的数目或符合特定条件的行的数目
count()函数有两种使用方式:
①使用count(*)对表中行的数目进行计数,不管表列中包含的是空值(null)还是非空值
②使用count(column)对特定列中具有值的行进行计数,忽略null值;
例6:
mysql> SELECT COUNT(*) AS count_roleinfo FROM roleinfo;
+----------------+
| count_roleinfo |
+----------------+
| 3 |
+----------------+
这条SQL语句利用count(*)对roleinfo表中所有行计数,计数值在count_roleinfo中返回
例6_1:
mysql> SELECT COUNT(level) AS count_level FROM roleinfo WHERE level > 100;
+-------------+
| count_level |
+-------------+
| 3 |
+-------------+
这条SQL语句使用COUNT(level)对level列中值大于100的行进行计数
注:
如果指定列名,则指定列的值为空的行被count()函数忽略,但如果count()函数中用的是星号(*),则不忽略
max()返回指定列中的最大值,max()要求指定列名
例7:
mysql> SELECT MAX(level) AS max_level FROM roleinfo;
+-----------+
| max_level |
+-----------+
| 201 |
+-----------+
这条SQL语句中返回roleinfo表中level列的最大值
例7_1:
mysql> SELECT MAX(changetime) AS max_time FROM roleinfo WHERE career = 2;
+---------------------+
| max_time |
+---------------------+
| 2019-01-12 22:40:22 |
+---------------------+
这条SQL语句中增加了过滤条件(career = 2),返回roleinfo表中career = 2时changetime列的最大值
注:
1、MySQL允许max()用来返回任意列中的最大值,包括返回文本列的最大值;但用于文本数据时,如果数据按相应的列排序,则max()返回最后一行
2、max()函数忽略列值为null的行
min()返回指定列的最小值,min()也要求指定列名
例8:
mysql> SELECT MIN(changetime) AS min_changetime FROM roleinfo WHERE career = 2;
+---------------------+
| min_changetime |
+---------------------+
| 2019-01-12 22:38:19 |
+---------------------+
注:
1、MIN()函数与MAX()函数类似。MySQL允许min()用来返回任意列中的最小值,包括返回文本列的最小值;但用于文本数据时,如果数据按相应的列排序,则min()返回最前面的行
2、min()函数忽略列值为null的行
sum()函数用来返回指定列值的和(总计)
例9:
mysql> SELECT SUM(level) AS total_level FROM roleinfo WHERE career = 2;
+-------------+
| total_level |
+-------------+
| 208 |
+-------------+
函数sum()返回roleinfo表中所有level列的值之和,where子句保证只统计某个指定列的数值
例9_1:
mysql> SELECT SUM(level*career) AS total_level FROM roleinfo WHERE career = 2;
+-------------+
| total_level |
+-------------+
| 416 |
+-------------+
函数sum()返回roleinfo表中level*career之积的和
注:
1、利用标准的算数操作符,所有聚集函数都可用来执行多个列上的计算
2、sum()函数忽略列值为null的行
MySQL5.0.3以及之后的版本,聚集函数和distinct可以搭配使用,比如:
①对所有的行执行计算,指定all参数或不给参数(all是默认所有行为,不需要指定,如果不指定distinct,则假定为all)
②只包含不同的值,指定distinct参数;只计算值不同的行
③如果指定列名,则distinct只能用于count();distinct不能用于count(*),因此不允许使用count(distinct);distinct必须使用列名,不能用于计算或者表达式
④虽然distinct从技术上来说是可用于MIN()函数和MAX()函数的,但这样做实际上是没有价值的。一个列中的最小值和最大值都是相同的
例10:
mysql> SELECT AVG( DISTINCT level) AS avg_level FROM roleinfo WHERE career = 2;
+-----------+
| avg_level |
+-----------+
| 52.0000 |
+-----------+
这条SQL语句中,使用avg()函数返回level列中career = 2的对应的等级的平均价格,因为使用了distinct参数,因此平均值只考虑不同的值(唯一值)
例10_1:
mysql> SELECT COUNT(DISTINCT level) AS count_level FROM roleinfo;
+-------------+
| count_level |
+-------------+
| 2 |
+-------------+
这条SQL语句中,只计算了level值为不同时的行数
select语句可以包含多个聚集函数
例11:
mysql> SELECT COUNT(*) AS count_roleinfo,
-> MIN(level) AS min_level,
-> MAX(career) AS max_career,
-> AVG(CAMP) as avg_camp
-> FROM roleinfo;
+----------------+-----------+------------+----------+
| count_roleinfo | min_level | max_career | avg_camp |
+----------------+-----------+------------+----------+
| 3 | 3 | 2 | 2.3333 |
+----------------+-----------+------------+----------+
这条SQL语句,使用了单条select语句执行4个聚集计算,返回四个值(roleinfo表中的行数、level的最小值、career的最大值以及camp的平均值)
注:
在指定别名以包含某个聚集函数的结果时,不应该使用表中实际的列名;这样便于使用SQL更加容易和理解,以及排除方便排除错误。
分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算
在MySQL中,分组是在SELECT语句中的GROUP BY子句中建立的
例12:
mysql> SELECT total_price,count(*) AS new_price FROM price GROUP BY total_price;
+-------------+-----------+
| total_price | new_price |
+-------------+-----------+
| 1002 | 2 |
| 1003 | 4 |
| 1004 | 2 |
| 1005 | 2 |
+-------------+-----------+
注:
1、上面例子中指定了两个列,total_price为目标列(用于分组的列),new_price为计算字段(由count(*)函数建立)。GROUP BY子句指示MYSQL按total_price排序并分组数据,这导致对每个total_price计算而不是对整个表(列)计算
2、因为使用了GROUP BY,就不必指定要计算和估值的每个组了,系统会自动完成。GROUP BY子句指示指示MySQL分组数据,然后都每个组而不是整个结果集进行聚集
1、GROUP BY子句可以包含任意数目的列,这使得可以对分组进行嵌套,为数据分组提供更细致的控制
2、如果在GROUP BY子句中嵌套了分组,数据将在最后规定的分组上进行汇总。即:在建立分组时,指定的所有列都一起计算(所以不能从个别列取回数据)
3、GROUP BY子句中列出的每个列都必须是检索列或有效的表达式(但不能是聚集函数),如果在select中使用表达式,则必须在GROUP BY子句中指定相同的表达式(不能使用别名)
4、除了聚集计算语句外,select语句中的每个列都必须在GROUP BY子句中给出
5、如果分组列中具有null值,则null将作为一个分组返回(如果列中有多行null值,他们将分为一组)
6、GROUP BY子句必须出现在WHERE子句之后,ORBER BY子句之前
PS:使用with rollup关键字,可以得到每个分组以及每个分组汇总级别(针对每个分组)的值。
1、除了使用GROUP BY分组数据外,MYSQL还允许过滤分组,规定包括哪些分组,排除哪些分组。为了得出这种数据,必须基于完整的分组而不是个别的行进行过滤
2、在进行分组过滤时不能使用WHERE关键字,因为WHERE过滤指定的是行而不是分组,事实上WHERE没有分组的概念。为此MYSQL提供了另外的子句,那就是HAVING子句。HAVING非常类似于WHERE,唯一的区别是WHERE过滤行,而HAVING过滤分组
例13:
mysql> SELECT total_price,count(*) AS new_price FROM price GROUP BY total_price HAVING count(*)>= 3;
+-------------+-----------+
| total_price | new_price |
+-------------+-----------+
| 1003 | 4 |
+-------------+-----------+
注:
这条SQL语句中的having子句过滤出count(*)>=3(3个以上的分组)的那些分组
1、WHERE在数据分组前进行过滤,HAVING在数据分组后进行过滤;where排除的行不包括在分组中(这可能会改变计算值,从而影响having子句中基于这些值过滤掉的分组)
2、WHERE过滤行,而HAVING过滤分组
例14:
mysql> SELECT total_price,count(*) AS new_price FROM price WHERE current_price=8 GROUP BY total_price;
+-------------+-----------+
| total_price | new_price |
+-------------+-----------+
| 1003 | 4 |
| 1004 | 1 |
+-------------+-----------+
例14_1:
mysql> SELECT total_price,count(*) AS new_price FROM price WHERE current_price=8 GROUP BY total_price HAVING count(*)>= 2;
+-------------+-----------+
| total_price | new_price |
+-------------+-----------+
| 1003 | 4 |
+-------------+-----------+
注:
WHERE子句过滤出current_price=8的行,然后按照total_price分组数据,HAVING子句再过滤出计数大于等于2的分组
虽然GROUP BY和ORDER BY经常完成相同的 工作,但它们之间有很大的不同
ORDER BY | GROUP BY |
排序产生的输出 | 分组行,但输出可能不是分组的顺序 |
任意列都可以使用,甚至非选择的列也可以使用 | 只可使用选择列或表达式列,而且必须使用每个选择列表达式 |
不一定需要 | 如果与聚集函数一起使用列(或表达式),则必须使用 |
注:一般使用group by子句时,也应该给出order by子句,这是保证数据正确排序的唯一方法(千万不要依赖group by排序数据)
例15:
mysql> SELECT total_price,SUM(current_price) AS new_price FROM price GROUP BY total_price;
+-------------+-----------+
| total_price | new_price |
+-------------+-----------+
| 1002 | 10 |
| 1003 | 39 |
| 1004 | 13 |
| 1005 | 6 |
+-------------+-----------+
例15_1:
mysql> SELECT total_price,SUM(current_price) AS new_price FROM price GROUP BY total_price HAVING SUM(current_price) >= 6 ORDER BY new_price;
+-------------+-----------+
| total_price | new_price |
+-------------+-----------+
| 1005 | 6 |
| 1002 | 10 |
| 1004 | 13 |
| 1003 | 39 |
+-------------+-----------+
子句 | 说明 | 是否必须使用 |
SELECT | 要返回的列或表达式 | 是 |
FROM | 从中检索数据的表 | 仅在从表中选择数据时使用 |
WHERE | 行级过滤 | 否 |
GROUP BY | 分组说明 | 仅在按组计算聚集时使用 |
HAVING | 组级过滤 | 否 |
ORDER BY | 输出排序顺序 | 否 |
LIMIT | 要检索的行数 | 否 |