MySQL快速回顾:计算字段与函数

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: MySQL快速回顾:计算字段与函数

9.1 计算字段

存储在数据库表中的数据一般不是应用程序所需要的格式。比如:

  • 如果想要在一个字段中既显示公司名,又显示公式的地址,但这两个信息一般包含在不同的表列中。
  • 城市、州和邮政编码存储在不同的列中,但邮件标签打印程序却需要把它们作为一个恰当格式的字段检索出来。
  • 列数据是大小写混合的,但报表程序需要把所有数据按大写表示出来。

在上面举的例子中,存储在表中的数据都不是应用程序所需要的。我们需要直接数据库中检索出转换、计算或格式化过的数据;而不是检索出数据,然后在客户机应用程序或报告程序中重新格式化。

所以就需要计算字段。计算字段并不实际存储于数据库表中,而是运行时在SELECT语句内创建的。

这里的字段(field)基本上跟列(column)的意思相同,经常互换使用,不过数据库列一般称为列,而术语字段通常用在计算字段的连接上。

可在SQL语句内完成的许多转换和格式化工作都可以直接在客户机应用程序内完成。但是一般来说,在数据库服务器上完成这些操作比在客户机中完成要快得多,因为DBMS是设计来快速地完成这种处理的。

9.1.1 计算字段的使用

举一个创建由两列组成的标题的简单例子。

vendors表包含供应商名和位置信息。假如要生成一个供应商报表,需要在供应商的名字中按照name(location)这样的格式列出供应商的位置。

此报表需要单个值,而表中数据存储在两个列vend_name和vend_country中。此外,需要用括号将vend_country括起来,这些东西都没有明确存储在数据库表中。来看看如何用SELECT来编写这样的格式。

拼接(concatenate)将值联结到一起构成单个值。

解决的方法就是将两个列拼接起来。在MySQL的SELECT语句中,可使用CONCAT()函数来拼接两个列。

多数DBMS使用+或者||来实现拼接,而MySQL则使用Concat()函数来实现。当把SQL语句转换成MySQL语句时一定要把这个区别铭记在心。

结果:

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

输出:

+-------------------------------------------+
| CONCAT(vend_name, '(', vend_country, ')') |
+-------------------------------------------+
| ACME(USA)                                 |
| Anvils R Us(USA)                          |
| Jet Set(England)                          |
| LT Supplies(USA)                          |
+-------------------------------------------+
4 rows in set (0.06 sec)

解释:

  • CONCAT()拼接串),即把多个串连接起来形成一个较长的串。CONCAT()需要一个或多个指定的串,各个串之间用逗号分隔。(关于更多函数的使用后面会讲)
  • 上面的SELECT语句连接以下4个元素:
  • 存储在vend_name列中的名字;
  • 包括一个空格和一个左圆括号的串;
  • 存储在vend_country列中的国家;
  • 包括一个右圆括号的串。

9.1.2 使用别名

你拿上面那条语句去执行,会发现新计算出的列名,列名好长而且列名的意义不能明确看出。实际上它是没有名称,它只是一个值。如果仅在SQL查询工具中查看一下结果,这样没什么不好。但是,一个未命名的列不能用于客户机应用中,因为客户机没有办法引用它。这时候SQL就引出别名。

别名(alias)是一个字段或值的替换名。别名用AS关键字赋予。

使用别名修改上面的SQL语句

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

AS也可省略,只要在需要重命名的后面空一格。

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

输出:

+------------------+
| vend_title       |
+------------------+
| ACME(USA)        |
| Anvils R Us(USA) |
| Jet Set(England) |
| LT Supplies(USA) |
+------------------+
4 rows in set (0.06 sec)

这样任何客户机都可以按别名引用这个列,看起来是一个实际的表列一样。

别名不止用于计算字段中,还可以在实际的表列名包含不符合规定的字符(含空格)时重新命名它,在原来的名字含混或容易误解时扩充它,等。但记住,并不是真正会去重命名表中的实际列名。

别名有时候也称为导出列(derived column),不管称为什么,它们所代表的都是相同的东西。

9.1.3 执行算术计算

计算字段的另一常见用途是读检索出的数据进行算术计算。比如,一个订单表order中含有物品价格price和物品数量quantity,需要求物品总价格。那么只需要 物品价格乘以物品数据即可。

SELECT order_id, order_price*order_quantiry 
 AS expanded_price
 FROM order;

MySQL算术操作符:+、-、*、/。

SELECT可用通过使用计算字段来测试。

SELECT 2*3;

小结:介绍了计算字段以及如何创建计算字段。此外还学了如何创建和使用别名,以便应用程序能引用计算字段。

9.2 函数

SQL支持利用函数来处理数据。

可移植性(portable): 能运行在多个系统上的代码。

多数SQL语句是可移植的,在SQL实现之间有差异时,这些差异通常不那么难处理。而函数的可移植性却不强。几乎每种主要的DBMS的实现都支持其他实现不支持的函数,而且有时差异还很大。

为了代码的可移植性,很多SQL程序员不赞成使用特殊实现的功能。虽然这样有好处,但是不使用这些函数,编写某些应用程序代码会很难。

如果决定使用函数,应该保证做好代码注释,以便以后你(或其他人)能确切地知道所编写的SQL代码的含义。

9.2.1 使用函数

大多数SQL实现支持以下类型的函数

  • 用于处理文本串(如删除或填充值,转换值为大写或小写)的文本函数
  • 用于在数值上进行算术操作(如返回绝对值,进行代数运算)的数值函数。
  • 用于处理日期和时间值并从这些值中提取特定成分(例如,返回两个日期之差,检查日期有效性等)的日期和时间函数。
  • 返回DBMS正使用的特殊信息(如返回用户登录信息,检查版本细节)的系统函数

9.2.2 文本处理函数

之前已经介绍TRIM():去空格的函数。类似的函数如下:

参考:菜鸟教程

函数 说明 演示
LEFT(s,n) 返回字符串 s 的前 n 个字符 返回字符串 runoob 中的前两个字符:SELECT LEFT('runoob',2) -- ru
RIGHT(s,n) 返回字符串 s 的后 n 个字符 返回字符串 runoob 的后两个字符:SELECT RIGHT('runoob',2) -- ob
LOWER(s) 将串转换为小写 把字符串 Runoob 全转小写: SELECT LOWER('Runoob') -- runoob
UPPER(s) 将串转换为大写 返回字符串 runoob 全转小写:SELECT UPPER('Runoob') -- RUNOOB
TRIM(s) 去掉串的左右空格 去掉字符串 空格runoob空格 的空格:SELECT TRIM(' runoob ') -- runoob
LTRIM(s) 去掉串左边的空格 去掉字符串 空格runoob空格 的左空格:SELECT LTRIM(' runoob ') -- runoob空格
RTRIM(s) 去掉串右边的空格 去掉字符串 空格runoob空格 的右空格:SELECT RTRIM(' runoob ') -- 空格runoob
SOUNDEX() 返回串的SOUNDEX值 看下面的解释
SUBSTRING(s, start, length) 从字符串 s 的 start 位置截取长度为 length 的子字符串 从字符串 RUNOOB 中的第 2 个位置截取 3个 字符:SELECT SUBSTRING("RUNOOB", 2, 3) AS ExtractString; -- UNO
LOCATE(s1,s) 从字符串 s 中获取 s1 的开始位置 获取 b 在字符串 abc 中的位置:SELECT LOCATE('st','myteststring'); -- 5返回字符串 abc 中 b 的位置:SELECT LOCATE('b', 'abc') -- 2
LENGTH() 返回串的长度 返回字符串 runoob 的长度:SELECT LENGTH('runoob') -- 6

上面的SOUNDEX需要进一步解释:SOUNDEX是一个而将任何文本串转换为描述其语音表示的字母数字模式的算法。SOUNDEX考虑了类似的发音字符和音节,使得能对串进行发音比较而不是字母比较。虽然SOUNDEX不是SQL概念,但MySQL(就像很大DBMS一样)都提供对SOUNDEX的支持。

比如,创建一张表名为customers,表中包含顾客(cust_name)和联系名(cust_contact)。

CREATE TABLE customers(
    cust_name varchar(20) PRIMARY KEY,
    cust_contact varchar(20)
);

现在假设有一个顾客Coyote Inc. , 其联系名为 Y.Lee。但如果这是输入错误的结果,此联系名实际应该是Y.Lie,怎么办?显然,按正确的联系名搜索不会返回数据,如下:

SELECT cust_name, cust_contact
FROM customers
WHERE cust_contact = 'Y.Lie';

输出:

Empty set

现在试下使用SOUNDEX()函数进行搜索,它匹配所有发音类似于Y.Lie的联系名:

SELECT cust_name, cust_contact
FROM customers
WHERE SOUNDEX(cust_contact) = SOUNDEX('Y.Lie');

输出:

+-------------+--------------+
| cust_name   | cust_contact |
+-------------+--------------+
| Coyote Inc. | Y.Lee        |
+-------------+--------------+
1 row in set (0.05 sec)

在这个例子中,WHERE子句使用SOUNDEX()函数来转换cust_contact列值和搜索串为它们的SOUNDEX值。因为Y.Lee和Y.lie发音相似,所以它们的SOUNDEX值匹配,因此WHERE子句正确地过滤了所需的数据。

9.2.3 日期和时间处理函数

日期和时间采用相应的数据类型和特殊的格式存储,以便快速和有效地排序或过滤,并节省物理存储空间。

一般,应用程序不使用来存储日期和时间的格式,因此日期和时间函数总是被用来读取、统计和处理这些值。所以,日期和时间函数在MySQL语言中很重要。

表格转载:菜鸟教程

函数 说明 演示
ADDDATE(d,n) 计算起始日期 d 加上 n 天的日期 SELECT ADDDATE("2020-01-15", 3);
SELECT ADDDATE("2020-01-15", INTERVAL 3 DAY);
->(2020-01-18)
ADDTIME(t,n) 时间 t 加上 n 秒的时间 SELECT ADDTIME('2011-11-11 11:11:11', 5);
->2011-11-11 11:11:16 (秒)
CURDATE() 返回当前日期 SELECT CURDATE();
->2020-01-15
CURTIME() 返回当前时间 SELECT CURTIME();
->16:41:01
DATE() 从日期或日期时间表达式中提取日期值 SELECT DATE("2020-01-15");
->2020-01-15
DATEDIFF(d1,d2) 计算日期 d1->d2 之间相隔的天数 SELECT DATEDIFF("2020-01-15","2020-01-4");
->11(前面的日期减去后面的日期)
DATE_ADD(d,INTERVAL expr type) 计算起始日期 d 加上一个时间段后的日期 SELECT ADDDATE('2011-11-11 11:11:11',1);
-> 2011-11-12 11:11:11 (默认是天)
SELECT ADDDATE('2011-11-11 11:11:11', INTERVAL 5 MINUTE);
-> 2011-11-11 11:16:11 (TYPE的取值与上面那个列出来的函数类似)
DATE_FORMAT(d,f) 按表达式 f的要求显示日期 d SELECT DATE_FORMAT('2011-11-11 11:11:11','%Y-%m-%d %r')
-> 2011-11-11 11:11:11 AM
DAY(d) 返回日期值 d 的日期部分 SELECT DAY("2020-01-15");
-> 15
DAYOFWEEK(d) 日期 d 今天是星期几,1 星期日,2 星期一,以此类推 SELECT DAYOFWEEK("2020-01-15");
-> 4
HOUR(t) 返回 t 中的小时值 SELECT HOUR("2020-01-15 17:21");
-> 17
MINUTE(t) 返回 t 中的分钟值 SELECT MINUTE("2020-01-15 17:21");
-> 21
MONTH(d) 返回日期d中的月份值,1 到 12 SELECT MONTH("2020-01-15 17:21");
-> 1
NOW() 返回当前日期和时间 SELECT NOW();
-> 2020-01-15 17:24:18
MICROSECOND(date) 返回日期参数所对应的微秒数 SELECT MICROSECOND("2017-06-20 09:34:00.000023");
-> -> 23
TIME(expression) 提取传入表达式的时间部分 SELECT TIME("19:30:10");
-> 19:30:10
YEAR(t) 返回t日期中的年份 SELECT YEAR("2020-01-15 17:21");
-> 2020

更多参考:菜鸟教程

需要注意的是MySQL使用的日期格式。无论是什么时候指定一个日期,或是插入或更新等,日期必须为格式yyyy-mm-dd。所以,2020年1月15号,给出的是2020-01-15.虽然其他的日期格式可能也行,但这是首选的日期格式,因为它排除了多义性(如,04/05/06是2006年5月4号还是2006年4月5号或...)。

应该总是使用4位数字的年份。MySQL虽然支持2位数字的年份,比如处理00-69位2000-2069。虽然它们可能是打算要的年份,但使用完整的4位数字年份更可靠。

在数据库表中检索时间日期,比如:

SELECT cust_id, order_num
FROM orders
WHERE order_date = '2005-09-01';

这样写的 order_date = '2005-09-01' 可靠吗?如果order_date的数据类型是datetime,这种类型存储日期及时间值,那么在例表中的值全都具有时间值00:00:00,但实际上很可能并不总是这样。如果用当前日期和时间存储订单日期(因此我们得知道订单日期和下订单当前的时间),怎么办??比如,存储的order_date值为2005-09-01 11:30:05,则WHERE order_date = '2005-09-01'就失败。

解决的方式:让MySQL仅将给出的日期与列中的日期部分进行比较,而不是将给出的日期与整个列值进行比较。所以得使用DATE()函数。DATE(order_date)表示MySQL仅提取列的日期部分,所以修改如下:

SELECT cust_id, order_num
FROM orders
WHERE DATE(order_date) = '2005-09-01';

所以,对于日期的数据要特别注意,如果要的是日期,使用DATE(),如果要的是天,使用DAY(),如果要的是月,使用MONTH()等。最好明确要的是什么格式的日期,即使知道相应的列只包含日期也应该加上函数。

还有一种日期比较需要说明。如果要检索2005年9月下的所有订单,怎么办??简单的相等测试肯定不行,因为它也要匹配月份中的天数。提供以下的解决方法:

SELECT cust_id, order_num
FROM orders
WHERE DATE(order_date) BETWEEN '2005-09-01' AND '2005-09-30';

其中,BETWEEN操作符用来把2005-09-01和2005-09-30定义为一个要匹配的日期范围。

还有另一种:

SELECT cust_id, order_num
FROM orders
WHERE YEAR(order_date) = 2005 AND MONTH(order_date) = 9;

解释:YEAR()是一个从日期(或日期时间)中返回年份的函数。类似,MONTH从日期中返回月份。因此WHERE YEAR(order_date) = 2005 AND MONTH(order_date) = 9检索出order_date为2005年9月的所有行。

9.2.3 数值处理函数

数值处理函数仅处理数值数据。一般主要用于代数、三角或几何运算。

在主要DBMS的函数中,数值函数是最统一最一致的函数。

函数 说明
ABS(t) 返回数t的绝对值
COS(t) 返回角度为t的余弦
EXP(t) 返回数t的指数值
MOD(a, b) 返回除操作(a/b)的余数 = (a%b)
PI() 返回圆周率
RAND() 返回一个随机数
SIN(t) 返回角度为t的正弦
SQRT(t) 返回数t的平方根
TAN(t) 返回角度为t的正切

小结:介绍了如何使用SQL的数据处理函数,主要注意日期函数的使用。这些函数不需要死记硬背,忘了就拿出来看。当然,最好简单的函数就记一记,比如:ABS()、SQRT()、YEAR()、HOUR()、DAY()等这些。

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
19天前
|
存储 SQL 关系型数据库
MySQL基础:函数
本文介绍了MySQL中几种常用的内建函数,包括字符串函数、数值函数、日期函数和流程函数。字符串函数如`CONCAT()`用于拼接字符串,`TRIM()`用于去除字符串两端的空格,`MOD()`求余数,`RAND()`生成随机数,`ROUND()`四舍五入。日期函数如`CURDATE()`返回当前日期,`NOW()`返回当前日期和时间,`DATE_ADD()`添加时间间隔,`DATEDIFF()`计算日期差。流程函数如`IF()`和`CASE WHEN THEN ELSE END`用于条件判断。聚合函数如`COUNT()`统计行数,`SUM()`求和,`AVG()`求平均值
24 8
MySQL基础:函数
|
4天前
|
JSON 关系型数据库 MySQL
MySQL 8.0常用函数汇总与应用实例
这些函数只是MySQL 8.0提供的众多强大功能的一部分。通过结合使用这些函数,你可以有效地处理各种数据,优化数据库查询,并提高应用程序的性能和效率。
16 3
|
11天前
|
SQL 关系型数据库 MySQL
MySQL数据库中给表添加字段并设置备注的脚本编写
通过上述步骤,你可以在MySQL数据库中给表成功添加新字段并为其设置备注。这样的操作对于保持数据库结构的清晰和最新非常重要,同时也帮助团队成员理解数据模型的变化和字段的具体含义。在实际操作中,记得调整脚本以适应具体的数据库和表名称,以及字段的详细规范。
23 8
|
15天前
|
SQL 关系型数据库 MySQL
MySQL根据某个字段包含某个字符串或者字段的长度情况更新另一个字段的值,如何写sql
MySQL根据某个字段包含某个字符串或者字段的长度情况更新另一个字段的值,如何写sql
41 0
|
25天前
|
存储 关系型数据库 MySQL
MySQL MATCH 函数如何使用 WITH QUERY EXPANSION?
【9月更文挑战第2天】MySQL MATCH 函数如何使用 WITH QUERY EXPANSION?
28 0
|
27天前
|
存储 关系型数据库 MySQL
|
28天前
|
SQL 关系型数据库 MySQL
SQL Server、MySQL、PostgreSQL:主流数据库SQL语法异同比较——深入探讨数据类型、分页查询、表创建与数据插入、函数和索引等关键语法差异,为跨数据库开发提供实用指导
【8月更文挑战第31天】SQL Server、MySQL和PostgreSQL是当今最流行的关系型数据库管理系统,均使用SQL作为查询语言,但在语法和功能实现上存在差异。本文将比较它们在数据类型、分页查询、创建和插入数据以及函数和索引等方面的异同,帮助开发者更好地理解和使用这些数据库。尽管它们共用SQL语言,但每个系统都有独特的语法规则,了解这些差异有助于提升开发效率和项目成功率。
110 0
|
11天前
|
NoSQL 关系型数据库 MySQL
微服务架构下的数据库选择:MySQL、PostgreSQL 还是 NoSQL?
在微服务架构中,数据库的选择至关重要。不同类型的数据库适用于不同的需求和场景。在本文章中,我们将深入探讨传统的关系型数据库(如 MySQL 和 PostgreSQL)与现代 NoSQL 数据库的优劣势,并分析在微服务架构下的最佳实践。
|
13天前
|
存储 SQL 关系型数据库
使用MySQL Workbench进行数据库备份
【9月更文挑战第13天】以下是使用MySQL Workbench进行数据库备份的步骤:启动软件后,通过“Database”菜单中的“管理连接”选项配置并选择要备份的数据库。随后,选择“数据导出”,确认导出的数据库及格式(推荐SQL格式),设置存储路径,点击“开始导出”。完成后,可在指定路径找到备份文件,建议定期备份并存储于安全位置。
138 11
|
1月前
|
弹性计算 关系型数据库 数据库
手把手带你从自建 MySQL 迁移到云数据库,一步就能脱胎换骨
阿里云瑶池数据库来开课啦!自建数据库迁移至云数据库 RDS原来只要一步操作就能搞定!点击阅读原文完成实验就可获得一本日历哦~

热门文章

最新文章