SQL 入门 -- SQL 函数(三)
什么是 SQL 函数
SQL 中的函数一般是在数据上执行的,可以很方便地转换和处理数据。一般来说,当我们从数据表中检索出数据之后,就可以进一步对这些数据进行操作,得到更有意义的结果,比如返回指定条件的函数,或者求某个字段的平均值等。
常用的 SQL 函数有哪些
SQL 提供了一些常用的内置函数,你也可以自己定义 SQL 函数。SQL 的内置函数对于不同的数据库软件来说具有一定的通用性,常见内置函数分成四类:
1. 算术函数(算术处理)
2. 字符串函数(字符串处理)
3. 日期函数(日期处理)
4. 转换函数(数据类型转换)
函数是对提取出来的数据进行操作,那么数据表中字段类型的定义有哪几种呢?
我们经常会保存一些数值,不论是整数类型,还是浮点类型,实际上对应的就是数值类型。同样我们也会保存一些文本内容,可能是人名,也可能是某个说明,对应的就是字符串类型。此外我们还需要保存时间,也就是日期类型。那么针对数值、字符串和日期类型的数据,我们可以对它们分别进行算术函数、字符串函数以及日期函数的操作。如果想要完成不同类型数据之间的转换,就可以使用转换函数。
算术函数算术函数
顾名思义就是对数值类型的字段进行算术运算。
常用的算术函数及含义如下表所示:
SELECT ABS(-2),运行结果为 2。SELECT MOD(101,3),运行结果 2。SELECT ROUND(37.25,1),运行结果 37.3。
字符串函数
常用的字符串函数操作包括了字符串拼接,大小写转换,求长度以及字符串替换和截取等。具体的函数名称及含义如下表所示:
SELECT CONCAT('abc', 123),运行结果为 abc123。
SELECT LENGTH('你好'),运行结果为 6。
SELECT CHAR_LENGTH('你好'),运行结果为 2。
SELECT LOWER('ABC'),运行结果为 abc。
SELECT UPPER('abc'),运行结果 ABC。
SELECT REPLACE('fabcd', 'abc', 123),运行结果为 f123d。
SELECT SUBSTRING('fabcd', 1,3),运行结果为 fab。
日期函数
日期函数是对数据表中的日期进行处理,常用的函数包括:
SELECT CURRENT_DATE(),运行结果为 2019-04-03。
SELECT CURRENT_TIME(),运行结果为 21:26:34。
SELECT CURRENT_TIMESTAMP(),运行结果为 2019-04-03 21:26:34。
SELECT EXTRACT(YEAR FROM '2019-04-03'),运行结果为 2019。
SELECT DATE('2019-04-01 12:00:05'),运行结果为 2019-04-01。
这里需要注意的是,DATE 日期格式必须是 yyyy-mm-dd 的形式。
如果要进行日期比较,就要使用 DATE 函数,不要直接使用日期与字符串进行比较,会在后面的例子中讲具体的原因。
转换函数
转换函数可以转换数据之间的类型,常用的函数如下表所示:
SELECT CAST(123.123 AS INT),运行结果会报错。
SELECT CAST(123.123 AS DECIMAL(8,2)),运行结果为 123.12。
SELECT COALESCE(null,1,2),运行结果为 1。
CAST 函数在转换数据类型的时候,不会四舍五入,如果原数值有小数,那么转换为整数类型的时候就会报错。不过你可以指定转化的小数类型,在 MySQL 和 SQL Server 中,你可以用DECIMAL(a,b)来指定,其中 a 代表整数部分和小数部分加起来最大的位数,b 代表小数位数,比如DECIMAL(8,2)代表的是精度为 8 位(整数加小数位数最多为 8 位),小数位数为 2 位的数据类型。所以SELECT CAST(123.123 AS DECIMAL(8,2))的转换结果为 123.12。
用 SQL 函数对王者荣耀英雄数据做处理
王者荣耀英雄数据库,一共有 69 个英雄,23 个属性值。SQL 文件见 Github 地址:https://github.com/cystanford/sql_heros_data。
显示英雄以及他的物攻成长,对应字段为attack_growth。我们让这个字段精确到小数点后一位,需要使用的是算术函数里的 ROUND 函数。
SQL:SELECT name, ROUND(attack_growth,1) FROM heros
代码中,ROUND(attack_growth,1)中的attack_growth代表想要处理的数据,“1”代表四舍五入的位数,也就是我们这里需要精确到的位数。
假设我们想显示英雄最大生命值的最大值,就需要用到 MAX 函数。在数据中,“最大生命值”对应的列数为hp_max,在代码中的格式为MAX(hp_max)。
SQL:SELECT MAX(hp_max) FROM heros
假如我们想要知道最大生命值最大的是哪个英雄,以及对应的数值,就需要分成两个步骤来处理:首先找到英雄的最大生命值的最大值,即SELECT MAX(hp_max) FROM heros,然后再筛选最大生命值等于这个最大值的英雄,如下所示。
SQL:SELECT name, hp_max FROM heros WHERE hp_max = (SELECT MAX(hp_max) FROM heros)
假如我们想显示英雄的名字,以及他们的名字字数,需要用到CHAR_LENGTH函数。
SQL:SELECT CHAR_LENGTH(name), name FROM heros
假如想要提取英雄上线日期(对应字段 birthdate)的年份,只显示有上线日期的英雄即可(有些英雄没有上线日期的数据,不需要显示),这里我们需要使用 EXTRACT 函数,提取某一个时间元素。所以我们需要筛选上线日期不为空的英雄,即WHERE birthdate is not null,然后再显示他们的名字和上线日期的年份,即:
SQL: SELECT name, EXTRACT(YEAR FROM birthdate) AS birthdate FROM heros WHERE birthdate is NOT NULL
或者是
SQL: SELECT name, YEAR(birthdate) AS birthdate FROM heros WHERE birthdate is NOT NULL
假设我们需要找出在 2016 年 10 月 1 日之后上线的所有英雄。这里我们可以采用 DATE 函数来判断 birthdate 的日期是否大于 2016-10-01,即WHERE DATE(birthdate)>'2016-10-01',然后再显示符合要求的全部字段信息,即:
SQL: SELECT * FROM heros WHERE DATE(birthdate)>'2016-10-01'
需要注意的是下面这种写法是不安全的:
SELECT * FROM heros WHERE birthdate>'2016-10-01'
因为很多时候你无法确认 birthdate 的数据类型是字符串,还是 datetime 类型,如果你想对日期部分进行比较,那么使用DATE(birthdate)来进行比较是更安全的。
假设我们需要知道在 2016 年 10 月 1 日之后上线英雄的平均最大生命值、平均最大法力和最高物攻最大值。同样我们需要先筛选日期条件,即WHERE DATE(birthdate)>'2016-10-01',然后再选择AVG(hp_max), AVG(mp_max), MAX(attack_max)字段进行显示。
SQL: SELECT AVG(hp_max), AVG(mp_max), MAX(attack_max) FROM heros WHERE DATE(birthdate)>'2016-10-01'
关于大小写的规范
在 SQL 中,关键字和函数名是不用区分字母大小写的,比如 SELECT、WHERE、ORDER、GROUP BY 等关键字,以及 ABS、MOD、ROUND、MAX 等函数名。
不过在 SQL 中,你还是要确定大小写的规范,因为在 Linux 和 Windows 环境下,你可能会遇到不同的大小写问题。比如 MySQL 在 Linux 的环境下,数据库名、表名、变量名是严格区分大小写的,而字段名是忽略大小写的。而 MySQL 在 Windows 的环境下全部不区分大小写。
这就意味着如果你的变量名命名规范没有统一,就可能产生错误。这里有一个有关命名规范的建议:
- 关键字和函数名称全部大写;
- 数据库名、表名、字段名称全部小写;
- SQL 语句必须以分号结尾。
虽然关键字和函数名称在 SQL 中不区分大小写,也就是如果小写的话同样可以执行,但是数据库名、表名和字段名在 Linux MySQL 环境下是区分大小写的,因此建议你统一这些字段的命名规则,比如全部采用小写的方式。同时将关键词和函数名称全部大写,以便于区分数据库名、表名、字段名。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· 零经验选手,Compose 一天开发一款小游戏!
· 一起来玩mcp_server_sqlite,让AI帮你做增删改查!!