SQL 查询数据:创建计算字段

在日常 MySQL 数据查询中,我们常常需要基于表中现有字段生成新的计算结果(比如拼接姓名与性别、计算年龄差值、汇总数值等),这些动态生成的结果就是计算字段。计算字段不会存储在数据表中,而是在查询时实时计算,是提升数据查询灵活性的核心技巧。

本文将手把手教你掌握计算字段的核心用法。

什么是计算字段?

计算字段是通过对数据表中现有字段进行函数处理、算术运算、字符串拼接等操作,在SELECT查询中动态生成的虚拟字段。它的核心价值在于:无需修改数据表结构,就能按需生成业务所需的新数据,比如将 “姓名” 和 “性别” 拼接成 “用户昵称”,或基于 “年龄” 计算 “出生年份”。

拼接字段:把多个字段合并成一个

拼接字段是最常用的计算字段场景之一,比如将 “姓名” 和 “性别” 拼接成 “用户全称”,或将 “姓名” 和 “地址” 拼接成 “用户描述”。

在 MySQL 中主要通过CONCAT()函数实现拼接(注意:若拼接的字段包含NULL,结果会直接为NULL,可通过COALESCE()处理)。

基础拼接:姓名 + 性别

查询用户的 “姓名 + 性别” 组合(比如 “张三(男)”),并自定义字段名为user_fullname。如下:

> SELECT CONCAT(name, '(', gender, ')') AS user_fullname,phone FROM `user`

user_fullname|phone      |
-------------+-----------+
张三(男)        |13800138000|
李四(女)        |13800138001|
王五(男)        |13800138002|
赵六(女)        |13800138003|
孙七(男)        |13800138004|
周八(女)        |13800138005|
             |13800138006|
郑十(女)        |13800138007|
钱十一(男)       |13800138008|
孙十二(女)       |13800138009|

10 row(s) fetched.

注意,上面 “|13800138006|” 行因为性别 “gender” 为 NULL,因此拼接结果为 NULL。

处理 NULL 值的拼接:姓名 + 性别(兼容 NULL)

将性别为NULL的用户默认显示为 “未知”,再拼接姓名。如下:

> SELECT CONCAT(name, '(', COALESCE(gender, '未知'), ')') AS user_fullname,age FROM `user`

user_fullname|age|
-------------+---+
张三(男)        | 25|
李四(女)        | 30|
王五(男)        | 28|
赵六(女)        | 22|
孙七(男)        | 35|
周八(女)        | 27|
吴九(未知)       | 32|
郑十(女)        | 29|
钱十一(男)       | 24|
孙十二(女)       | 31|

10 row(s) fetched.

执行算术计算:对数值字段做运算

算术计算是计算字段的另一核心场景,支持+(加)、-(减)、*(乘)、/(除)、%(取余)等运算符,常用于数值字段的计算(比如年龄、金额、数量等)。

基础算术:根据年龄计算出生年份

假设当前年份是 2025 年,根据用户年龄计算出生年份(出生年份 = 2025 - 年龄)。

> SELECT name,age,2025-age AS birth_year FROM `user`

name|age|birth_year|
----+---+----------+
张三  | 25|      2000|
李四  | 30|      1995|
王五  | 28|      1997|
赵六  | 22|      2003|
孙七  | 35|      1990|
周八  | 27|      1998|
吴九  | 32|      1993|
郑十  | 29|      1996|
钱十一 | 24|      2001|
孙十二 | 31|      1994|

10 row(s) fetched.

注意,上述输出中 “birth_year” 是用户的出生日期。

条件算术:计算年龄差值(与平均年龄的差)

先计算所有用户的平均年龄,再查询每个用户的年龄与平均年龄的差值。

-- 第一步:计算平均年龄(约28.4岁)
> SELECT AVG(age) AS avg_age FROM `user`

avg_age|
-------+
28.3000|

1 row(s) fetched.

-- 第二步:计算每个用户与平均年龄的差值
-- ROUND() 保留1位小数
> SELECT name,age,ROUND(age - (SELECT AVG(age) FROM `user`), 1) AS age_diff FROM `user`

name|age|age_diff|
----+---+--------+
张三  | 25|    -3.3|
李四  | 30|     1.7|
王五  | 28|    -0.3|
赵六  | 22|    -6.3|
孙七  | 35|     6.7|
周八  | 27|    -1.3|
吴九  | 32|     3.7|
郑十  | 29|     0.7|
钱十一 | 24|    -4.3|
孙十二 | 31|     2.7|

10 row(s) fetched.

组合算术:年龄分组(按 10 岁为一组)

将用户按年龄分组(20-29 岁、30-39 岁),通过算术运算生成分组标识。

> SELECT name,age,CONCAT(FLOOR(age/10)*10, '-', (FLOOR(age/10)+1)*10-1, '岁') AS age_group FROM `user`

name|age|age_group|
----+---+---------+
张三  | 25|20-29岁   |
李四  | 30|30-39岁   |
王五  | 28|20-29岁   |
赵六  | 22|20-29岁   |
孙七  | 35|30-39岁   |
周八  | 27|20-29岁   |
吴九  | 32|30-39岁   |
郑十  | 29|20-29岁   |
钱十一 | 24|20-29岁   |
孙十二 | 31|30-39岁   |

10 row(s) fetched.

算术运算 + 筛选:查询年龄大于平均年龄的用户

筛选出年龄大于所有用户平均年龄的用户,并计算其年龄超出的部分。

> SELECT name, age, age-(SELECT AVG(age) FROM `user`) AS exceed_age
FROM `user` WHERE age > (SELECT AVG(age) FROM `user`)

name|age|exceed_age|
----+---+----------+
李四  | 30|    1.7000|
孙七  | 35|    6.7000|
吴九  | 32|    3.7000|
郑十  | 29|    0.7000|
孙十二 | 31|    2.7000|

5 row(s) fetched.

  

说说我的看法
全部评论(
没有评论
关于
本网站专注于 Java、数据库(MySQL、Oracle)、Linux、软件架构及大数据等多领域技术知识分享。涵盖丰富的原创与精选技术文章,助力技术传播与交流。无论是技术新手渴望入门,还是资深开发者寻求进阶,这里都能为您提供深度见解与实用经验,让复杂编码变得轻松易懂,携手共赴技术提升新高度。如有侵权,请来信告知:hxstrive@outlook.com
其他应用
公众号