07 计算字段的创建与使用 - 数据转换的艺术

本文是MySQL数据库系列教程的第七篇,将详细讲解如何创建和使用计算字段对数据进行灵活处理。

上一篇: 通配符模糊查询 - LIKE操作符的妙用

目录

一、什么是计算字段

[1.1 计算字段的概念](#1.1 计算字段的概念)

[1.2 为什么需要计算字段](#1.2 为什么需要计算字段)
二、拼接字段

[2.1 CONCAT函数](#2.1 CONCAT函数)

[2.2 拼接多个字段](#2.2 拼接多个字段)

[2.3 去除空格](#2.3 去除空格)
三、使用别名

[3.1 AS关键字](#3.1 AS关键字)

[3.2 别名的作用](#3.2 别名的作用)
四、执行算术计算

[4.1 基本算术操作符](#4.1 基本算术操作符)

[4.2 计算示例](#4.2 计算示例)

[4.3 复杂计算](#4.3 复杂计算)
五、综合实战


一、什么是计算字段

1.1 计算字段的概念

计算字段是在SELECT语句中创建的虚拟字段,它并不实际存在于数据库表中,而是在查询时动态生成的。

特点:

  • 运行时在SELECT语句内创建
  • 数据库提供计算字段,比在客户端完成转换更快
  • 只存在于查询结果中,不存储在数据库表中

1.2 为什么需要计算字段

在实际应用中,存储在数据库表中的数据格式往往不是应用程序需要的格式。

常见需求:

  • 将姓和名拼接成完整姓名
  • 将城市和国家组合成完整地址
  • 计算商品的总价(单价 × 数量)
  • 计算折扣后的价格
  • 格式化日期和时间

数据库 vs 客户端处理:

  • 数据库处理:速度快、效率高、减少网络传输
  • 客户端处理:增加应用负担、速度慢

最佳实践:在数据库层面进行数据转换,而不是在应用程序中处理。


二、拼接字段

2.1 CONCAT函数

CONCAT函数用于将多个字符串拼接成一个字符串。

语法:

sql 复制代码
CONCAT(string1, string2, string3, ...)

示例:创建供应商表

sql 复制代码
CREATE TABLE vendors (
    vendor_id INT PRIMARY KEY,
    vendor_name VARCHAR(100),
    vendor_city VARCHAR(50),
    vendor_country VARCHAR(50),
    contact_name VARCHAR(50)
);

INSERT INTO vendors VALUES
(1, '科技有限公司', '北京', '中国', '张伟'),
(2, '电子商务公司', '上海', '中国', '李娜'),
(3, '数码产品店', '深圳', '中国', '王强'),
(4, '智能设备厂', '杭州', '中国', '赵敏');

示例1:拼接供应商名称和城市

sql 复制代码
SELECT CONCAT(vendor_name, ' (', vendor_city, ')') 
FROM vendors;

结果:

复制代码
+-----------------------------------------------+
| CONCAT(vendor_name, ' (', vendor_city, ')')   |
+-----------------------------------------------+
| 科技有限公司 (北京)                           	|
| 电子商务公司 (上海)                           	|
| 数码产品店 (深圳)                            	|
| 智能设备厂 (杭州)                             	|
+-----------------------------------------------+

2.2 拼接多个字段

示例:拼接完整地址

sql 复制代码
SELECT CONCAT(vendor_city, ', ', vendor_country) 
FROM vendors;

结果:

复制代码
+-------------------------------------------+
| CONCAT(vendor_city, ', ', vendor_country) |
+-------------------------------------------+
| 北京, 中国                                	|
| 上海, 中国                                	|
| 深圳, 中国                               	|
| 杭州, 中国                                	|
+-------------------------------------------+

示例:创建客户表

sql 复制代码
CREATE TABLE customers (
    customer_id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    email VARCHAR(100),
    phone VARCHAR(20)
);

INSERT INTO customers VALUES
(1, '伟', '张', 'zhangwei@example.com', '13800138001'),
(2, '娜', '李', 'lina@example.com', '13900139001'),
(3, '强', '王', 'wangqiang@example.com', '13700137001'),
(4, '敏', '赵', 'zhaomin@example.com', '13600136001');

示例:拼接完整姓名

sql 复制代码
SELECT CONCAT(last_name, first_name) 
FROM customers;

结果:

复制代码
+-------------------------------+
| CONCAT(last_name, first_name) |
+-------------------------------+
| 张伟                           |
| 李娜                           |
| 王强                           |
| 赵敏                           |
+-------------------------------+

2.3 去除空格

TRIM函数家族:

  • TRIM() - 去除两端空格
  • LTRIM() - 去除左边空格
  • RTRIM() - 去除右边空格

示例:处理带空格的数据

sql 复制代码
CREATE TABLE test_spaces (
    id INT PRIMARY KEY,
    company_name VARCHAR(100)
);

INSERT INTO test_spaces VALUES
(1, '  苹果公司  '),
(2, '华为技术  '),
(3, '  小米科技');

-- 去除两端空格
SELECT id, TRIM(company_name) AS clean_name 
FROM test_spaces;

结果:

复制代码
+----+------------+
| id | clean_name |
+----+------------+
|  1 | 苹果公司    |
|  2 | 华为技术    |
|  3 | 小米科技    |
+----+------------+

组合使用CONCAT和TRIM:

sql 复制代码
SELECT CONCAT(TRIM(vendor_name), ' (', TRIM(vendor_city), ')') 
FROM vendors;

三、使用别名

3.1 AS关键字

**别名(Alias)**用于给计算字段指定一个有意义的名称。

语法:

sql 复制代码
SELECT column_expression AS alias_name 
FROM table_name;

示例1:为拼接字段指定别名

sql 复制代码
SELECT CONCAT(last_name, first_name) AS full_name,
       email,
       phone 
FROM customers;

结果:

复制代码
+-----------+------------------------+-------------+
| full_name | email                  | phone       |
+-----------+------------------------+-------------+
| 张伟      | zhangwei@example.com   | 13800138001 |
| 李娜      | lina@example.com       | 13900139001 |
| 王强      | wangqiang@example.com  | 13700137001 |
| 赵敏      | zhaomin@example.com    | 13600136001 |
+-----------+------------------------+-------------+

3.2 别名的作用

别名的优势:

  1. 使结果更易读
  2. 便于在应用程序中引用
  3. 可以在ORDER BY子句中使用
  4. 让SQL语句更清晰

示例2:多个别名

sql 复制代码
SELECT vendor_id,
       vendor_name AS company,
       CONCAT(vendor_city, ', ', vendor_country) AS location,
       contact_name AS contact 
FROM vendors;

结果:

复制代码
+-----------+------------------+-----------+---------+
| vendor_id | company          | location  | contact |
+-----------+------------------+-----------+---------+
|         1 | 科技有限公司     | 北京, 中国| 张伟   	 |
|         2 | 电子商务公司     | 上海, 中国| 李娜  	 |
|         3 | 数码产品店       | 深圳, 中国| 王强    	 |
|         4 | 智能设备厂       | 杭州, 中国| 赵敏    	 |
+-----------+------------------+-----------+---------+

示例3:在ORDER BY中使用别名

sql 复制代码
SELECT CONCAT(last_name, first_name) AS full_name,
       email 
FROM customers 
ORDER BY full_name;

注意:AS关键字是可选的,但建议使用,使SQL更清晰。


四、执行算术计算

4.1 基本算术操作符

MySQL支持以下算术操作符:

操作符 说明
+ 加法
- 减法
* 乘法
/ 除法

4.2 计算示例

示例:创建订单明细表

sql 复制代码
CREATE TABLE order_items (
    order_id INT,
    product_id INT,
    product_name VARCHAR(100),
    quantity INT,
    unit_price DECIMAL(10, 2),
    PRIMARY KEY (order_id, product_id)
);

INSERT INTO order_items VALUES
(1001, 1, 'iPhone 14 Pro', 2, 7999.00),
(1001, 2, 'AirPods Pro', 1, 1899.00),
(1002, 3, 'MacBook Pro', 1, 14999.00),
(1002, 4, 'iPad Air', 2, 4799.00),
(1003, 5, '小米13', 3, 3999.00),
(1003, 6, '小米平板', 2, 2299.00);

示例1:计算每个商品的总价

sql 复制代码
SELECT order_id,
       product_name,
       quantity,
       unit_price,
       quantity * unit_price AS total_price 
FROM order_items;

结果:

复制代码
+----------+---------------+----------+------------+-------------+
| order_id | product_name  | quantity | unit_price | total_price |
+----------+---------------+----------+------------+-------------+
|     1001 | iPhone 14 Pro |        2 |    7999.00 |    15998.00 |
|     1001 | AirPods Pro   |        1 |    1899.00 |     1899.00 |
|     1002 | MacBook Pro   |        1 |   14999.00 |    14999.00 |
|     1002 | iPad Air      |        2 |    4799.00 |     9598.00 |
|     1003 | 小米13        |        3 |    3999.00 |    11997.00 |
|     1003 | 小米平板      |        2 |    2299.00 |     4598.00 |
+----------+---------------+----------+------------+-------------+

示例2:计算折扣价格

sql 复制代码
CREATE TABLE products (
    product_id INT PRIMARY KEY,
    product_name VARCHAR(100),
    original_price DECIMAL(10, 2),
    discount_rate DECIMAL(3, 2)
);

INSERT INTO products VALUES
(1, 'iPhone 14', 5999.00, 0.85),
(2, 'MacBook Air', 9499.00, 0.90),
(3, 'iPad Pro', 8999.00, 0.88),
(4, '小米13', 3999.00, 0.80);

-- 计算折扣后价格
SELECT product_name,
       original_price,
       discount_rate,
       original_price * discount_rate AS discounted_price,
       original_price - (original_price * discount_rate) AS saved_amount 
FROM products;

结果:

复制代码
+--------------+----------------+---------------+------------------+--------------+
| product_name | original_price | discount_rate | discounted_price | saved_amount |
+--------------+----------------+---------------+------------------+--------------+
| iPhone 14    |        5999.00 |          0.85 |          5099.15 |       899.85 |
| MacBook Air  |        9499.00 |          0.90 |          8549.10 |       949.90 |
| iPad Pro     |        8999.00 |          0.88 |          7919.12 |      1079.88 |
| 小米13       |        3999.00 |          0.80 |          3199.20 |       799.80 |
+--------------+----------------+---------------+------------------+--------------+

4.3 复杂计算

示例:计算订单总额

sql 复制代码
-- 为订单表添加运费和税费
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_name VARCHAR(50),
    subtotal DECIMAL(10, 2),
    shipping_fee DECIMAL(10, 2),
    tax_rate DECIMAL(3, 2)
);

INSERT INTO orders VALUES
(1001, '张三', 17897.00, 20.00, 0.13),
(1002, '李四', 24597.00, 0.00, 0.13),
(1003, '王五', 16595.00, 15.00, 0.13);

-- 计算订单总金额
SELECT order_id,
       customer_name,
       subtotal,
       shipping_fee,
       subtotal * tax_rate AS tax_amount,
       subtotal + shipping_fee + (subtotal * tax_rate) AS total_amount 
FROM orders;

结果:

复制代码
+----------+---------------+----------+--------------+------------+--------------+
| order_id | customer_name | subtotal | shipping_fee | tax_amount | total_amount |
+----------+---------------+----------+--------------+------------+--------------+
|     1001 | 张三          | 17897.00 |        20.00 |    2326.61 |     20243.61 |
|     1002 | 李四          | 24597.00 |         0.00 |    3197.61 |     27794.61 |
|     1003 | 王五          | 16595.00 |        15.00 |    2157.35 |     18767.35 |
+----------+---------------+----------+--------------+------------+--------------+

示例:计算平均单价

sql 复制代码
SELECT order_id,
       product_name,
       quantity,
       unit_price,
       quantity * unit_price AS total_price,
       (quantity * unit_price) / quantity AS avg_unit_price 
FROM order_items;

五、综合实战

让我们创建一个完整的电商订单系统,综合运用计算字段:

sql 复制代码
-- 创建商品表
CREATE TABLE shop_products (
    product_id INT PRIMARY KEY,
    product_code VARCHAR(50),
    product_name VARCHAR(100),
    category VARCHAR(50),
    cost_price DECIMAL(10, 2),
    selling_price DECIMAL(10, 2),
    stock_quantity INT
);

INSERT INTO shop_products VALUES
(1, 'ELEC-001', 'iPhone 14 Pro', '电子产品', 6500.00, 7999.00, 50),
(2, 'ELEC-002', 'MacBook Pro', '电子产品', 11000.00, 14999.00, 30),
(3, 'ELEC-003', '小米13', '电子产品', 3200.00, 3999.00, 100),
(4, 'HOME-001', '智能音箱', '家居用品', 150.00, 299.00, 200),
(5, 'HOME-002', '扫地机器人', '家居用品', 1200.00, 1999.00, 80);

-- 1. 计算商品利润和利润率
SELECT product_code,
       product_name,
       cost_price,
       selling_price,
       selling_price - cost_price AS profit,
       ((selling_price - cost_price) / cost_price * 100) AS profit_rate 
FROM shop_products;

-- 2. 计算库存总价值
SELECT product_name,
       stock_quantity,
       cost_price,
       stock_quantity * cost_price AS inventory_value 
FROM shop_products;

-- 3. 创建完整的商品信息显示
SELECT CONCAT(product_code, ' - ', product_name) AS product_info,
       category,
       CONCAT('¥', selling_price) AS price,
       CONCAT(stock_quantity, '件') AS stock 
FROM shop_products;

-- 4. 创建员工表,计算年薪
CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50),
    department VARCHAR(50),
    monthly_salary DECIMAL(10, 2),
    bonus_rate DECIMAL(3, 2)
);

INSERT INTO employees VALUES
(1, '伟', '张', '技术部', 15000.00, 0.20),
(2, '娜', '李', '市场部', 12000.00, 0.25),
(3, '强', '王', '技术部', 10000.00, 0.15),
(4, '敏', '赵', '人事部', 8000.00, 0.10);

-- 计算员工年薪(含奖金)
SELECT CONCAT(last_name, first_name) AS full_name,
       department,
       monthly_salary,
       monthly_salary * 12 AS annual_salary,
       monthly_salary * 12 * bonus_rate AS annual_bonus,
       monthly_salary * 12 * (1 + bonus_rate) AS total_annual_income 
FROM employees;

-- 5. 创建销售记录表
CREATE TABLE sales_records (
    sale_id INT PRIMARY KEY,
    sale_date DATE,
    product_name VARCHAR(100),
    quantity INT,
    unit_price DECIMAL(10, 2),
    discount DECIMAL(3, 2)
);

INSERT INTO sales_records VALUES
(1, '2024-03-01', 'iPhone 14 Pro', 2, 7999.00, 0.95),
(2, '2024-03-05', 'MacBook Pro', 1, 14999.00, 0.90),
(3, '2024-03-10', '小米13', 3, 3999.00, 0.85),
(4, '2024-03-15', '智能音箱', 5, 299.00, 1.00),
(5, '2024-03-20', '扫地机器人', 2, 1999.00, 0.92);

-- 计算销售详情
SELECT sale_id,
       sale_date,
       product_name,
       quantity,
       unit_price,
       quantity * unit_price AS subtotal,
       discount AS discount_rate,
       quantity * unit_price * discount AS final_amount,
       quantity * unit_price * (1 - discount) AS discount_amount 
FROM sales_records;

-- 6. 创建学生成绩表
CREATE TABLE student_scores (
    student_id INT PRIMARY KEY,
    student_name VARCHAR(50),
    chinese DECIMAL(5, 2),
    math DECIMAL(5, 2),
    english DECIMAL(5, 2)
);

INSERT INTO student_scores VALUES
(1, '张三', 85.5, 92.0, 88.5),
(2, '李四', 78.0, 85.5, 90.0),
(3, '王五', 92.5, 88.0, 85.0),
(4, '赵六', 88.0, 95.5, 92.5);

-- 计算总分和平均分
SELECT student_name,
       chinese,
       math,
       english,
       chinese + math + english AS total_score,
       (chinese + math + english) / 3 AS average_score 
FROM student_scores 
ORDER BY total_score DESC;

-- 7. 格式化显示
SELECT student_name,
       CONCAT(chinese, '分') AS chinese_score,
       CONCAT(math, '分') AS math_score,
       CONCAT(english, '分') AS english_score,
       CONCAT((chinese + math + english) / 3, '分') AS avg_score 
FROM student_scores;

-- 8. 创建会员积分表
CREATE TABLE member_points (
    member_id INT PRIMARY KEY,
    member_name VARCHAR(50),
    current_points INT,
    points_earned INT,
    points_used INT
);

INSERT INTO member_points VALUES
(1, '张伟', 1500, 2000, 500),
(2, '李娜', 3200, 3500, 300),
(3, '王强', 800, 1200, 400),
(4, '赵敏', 2500, 3000, 500);

-- 计算积分变化
SELECT member_name,
       current_points,
       points_earned,
       points_used,
       points_earned - points_used AS net_change,
       current_points + points_earned - points_used AS should_be_points 
FROM member_points;

-- 9. 复杂计算:计算商品性价比
SELECT product_name,
       category,
       selling_price,
       cost_price,
       selling_price - cost_price AS profit,
       CONCAT(ROUND((selling_price - cost_price) / selling_price * 100, 2), '%') AS profit_margin,
       CONCAT('库存价值: ¥', stock_quantity * cost_price) AS inventory_info 
FROM shop_products 
ORDER BY profit DESC;

-- 10. 综合查询:销售业绩分析
SELECT sale_date,
       product_name,
       CONCAT(quantity, ' × ¥', unit_price) AS sale_detail,
       quantity * unit_price AS original_amount,
       CONCAT(ROUND((1 - discount) * 100, 0), '%') AS discount_info,
       quantity * unit_price * discount AS actual_amount,
       quantity * unit_price * (1 - discount) AS saved_money 
FROM sales_records 
ORDER BY sale_date;

总结

本文详细介绍了计算字段的创建和使用:

  1. 拼接字段:使用CONCAT函数组合多个字段
  2. 去除空格:使用TRIM、LTRIM、RTRIM函数
  3. 使用别名:用AS关键字为计算字段指定有意义的名称
  4. 算术计算:使用+、-、*、/进行数值计算

关键要点:

  • 计算字段是运行时创建的,不存储在数据库中
  • 在数据库层面处理数据比在客户端更高效
  • 使用别名使结果更易读、更易用
  • 可以组合使用多个函数和操作符进行复杂计算

下一篇我们将学习MySQL的各种函数,进一步增强数据处理能力。


下一篇: MySQL函数处理数据 - 强大的数据处理工具箱

相关推荐
程序员云帆哥3 小时前
MySQL JDBC Driver URL参数配置规范
数据库·mysql·jdbc
TDengine (老段)3 小时前
TDengine 数学函数 FLOOR 用户手册
大数据·数据库·物联网·时序数据库·iot·tdengine·涛思数据
大气层煮月亮4 小时前
Oracle EBS ERP开发——报表生成Excel标准模板设计
数据库·oracle·excel
云和数据.ChenGuang4 小时前
达梦数据库的命名空间
数据库·oracle
三三木木七5 小时前
mysql拒绝连接
数据库·mysql
蹦跶的小羊羔5 小时前
sql数据库语法
数据库·sql
唐古乌梁海5 小时前
【mysql】InnoDB的聚簇索引和非聚簇索引工作原理
数据库·mysql
我变秃了也没变强5 小时前
pgsql配置密码复杂度策略
数据库·postgresql
PawSQL5 小时前
企业级SQL审核工具PawSQL介绍(1) - 六大核心能力
数据库·sql·oracle