场景
- 现在有一个表包含用户姓,名等信息,这些信息存储在不同列,现在应用场景需要一个完整的姓名,我们需要重新组合这些信息供应用程序使用
- 有一个订单列表,里面有商品的数量及单价,现在需要计算出总价以供应用程序使用
计算列
MySQL 的 Generated Column 又称为虚拟列或计算列。Generated Column列的值是在列定义时包含了一个计算表达式计算得到的,提供一种方便的方式来派生新的数据。
创建计算列
可以通过 GENERATED
和 AS
关键字来定义计算列,语法如下:
ALTER TABLE table_name
ADD column_name data_type GENERATED ALWAYS AS (expression) [VIRTUAL|STORED];
table_name
:表名column_name
:计算列的名称data_type
:计算列的数据类型expression
:计算表达式,用于定义计算列的值VIRTUAL
或STORED
:指定计算列的类型,VIRTUAL
表示虚拟列(不存储实际值),STORED
表示存储列(将计算结果存储在表中)
示例
- 虚拟列(VIRTUAL):
-- 创建一个表
CREATE TABLE products (
id INT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(255),
price DECIMAL(10, 2),
discount DECIMAL(5, 2),
discounted_price DECIMAL(10, 2) GENERATED ALWAYS AS (price * (1 - discount / 100)) VIRTUAL
);
-- 插入数据
INSERT INTO products (name, price, discount)
VALUES ('Product A', 100.00, 20.0);
-- 查询包括计算列的数据
SELECT id, name, price, discount, discounted_price FROM products;
- 存储列(STORED):
-- 创建一个表
CREATE TABLE employees (
id INT PRIMARY KEY AUTO_INCREMENT,
first_name VARCHAR(50),
last_name VARCHAR(50),
full_name VARCHAR(101) GENERATED ALWAYS AS (CONCAT(first_name, ' ', last_name)) STORED
);
-- 插入数据
INSERT INTO employees (first_name, last_name)
VALUES ('John', 'Doe');
-- 查询包括计算列的数据
SELECT id, first_name, last_name, full_name FROM employees;
计算字段
通过已有的列以及定义的计算规则来动态生成的新字段,并不实际存在于数据库表中。
拼接字段
将值联结到一起构成新的单个值。各DBMS方式不同有使用+ ,也有使用||来实现拼接, MySQL则使用Concat()函数去实现这一操作。
Concat()把多个字段连接起来形成新的的字段,各个字段之间用逗号分隔,如:
SELECT Concat(last_name, first_name) FROM employees;
可以看到最终以Concat(last_name, first_name)
列出了对应的组合值,但是这样不方便子句使用,那么我们可以用给这个组合取一个名,
别名(alias)是一个字段或值 的替换名。通过AS关键字设置
SELECT Concat(last_name, first_name) AS full_name FROM employees as e WHERE e.full_name = '张三';
可以看到最终以full_name名称显示,也方便子句使用,如:
SELECT Concat(last_name, first_name) AS full_name FROM employees ORDER BY full_name = '张三';
注意!在MySQL中,只可以在ORDER BY,GROUP BY和HAVING子句中的来引用该别名。 WHERE不行!!!
这涉及到MySql语句执行顺序,WHERE是在SELECT之前执行,所以SELECT命名的别名他无法使用!
执行顺序如下,
- FROM: 指定一个或多个表来选择数据。
- JOIN: 如果查询涉及多个表,进行连接操作,使用
ON
子句指定连接条件。 - WHERE: 对从
FROM
和JOIN
步骤得到的结果进行过滤。 - GROUP BY: 根据指定的列对数据进行分组。
- HAVING: 对分组后的结果进行过滤。
- SELECT: 选择要返回的列,进行计算或处理。
- DISTINCT: 根据指定的列对结果集进行去重。
- ORDER BY: 对结果进行排序。
- LIMIT: 限制返回的结果数量。
GROUP BY和HAVING子句也在之前为什么可以用别名 是因为MySQL对其做了特殊优化!
MySQL 具体处理了两个主要方面,使得在 GROUP BY
和 HAVING
子句中可以使用 SELECT
中的别名:
- 执行顺序优化:MySQL 在执行查询时,会按照一定的顺序执行各个子句,通常先执行
FROM
、JOIN
、WHERE
、GROUP BY
、HAVING
、SELECT
、ORDER BY
、LIMIT
。但是,MySQL 在执行SELECT
子句时会同时处理GROUP BY
和HAVING
子句,这意味着在SELECT
中定义的别名可以在GROUP BY
和HAVING
中使用。 - 隐式引用:MySQL 在执行查询时,会进行隐式引用。当使用别名时,MySQL 会先查找
SELECT
中是否有该别名,如果找不到,则再查找其他地方(如GROUP BY
和HAVING
)。这种隐式引用机制使得在HAVING
子句中可以使用SELECT
中的别名。
算术计算
通过数学计算得出新的字段, 如通过价格和折扣算出最终折扣价
其他
生成计算字段的方式不止上面这些,比如还有以下这些数据处理函数的方式:
- 数学函数: 如
ABS()
(绝对值)、ROUND()
(四舍五入)、CEILING()
(向上取整)、FLOOR()
(向下取整)等。 - 字符串函数: 如
UPPER()
(将字符串转换为大写)、LOWER()
(将字符串转换为小写)、SUBSTRING()
(提取子字符串)等。 - 日期和时间函数: 如
DATE_FORMAT()
(格式化日期)、DATEDIFF()
(计算日期之间的天数差)、NOW()
(获取当前日期和时间)等。 - 逻辑函数: 如
IF()
(条件判断)、CASE
表达式等。 - 聚合函数: 如
SUM()
、AVG()
、COUNT()
等,用于对数据进行汇总计算。 - 类型转换函数: 如
CAST()
、CONVERT()
,用于将一个数据类型转换为另一个数据类型。
文章评论