数据库——MySQL数字函数和子查询

一、数据库表结构设计

1. 患者表(patient)

记录患者基本信息:

sql 复制代码
CREATE TABLE patient (
    patientID INT PRIMARY KEY,
    patientName VARCHAR(50),
    birthDate DATE
);

示例数据

sql 复制代码
INSERT INTO patient VALUES
(1, '姚维新', '1990-05-15'),
(2, '夏颖', '1985-03-20'),
(3, '张三', '2000-01-10'),
(4, '李四', '1975-07-30'),
(5, '简要选', '1980-12-25');

2. 检查记录表(prescription)

记录患者的检查记录:

sql 复制代码
CREATE TABLE prescription (
    prescriptionID INT PRIMARY KEY,
    patientID INT,
    checkItemID INT,
    examDate DATE
);

示例数据

sql 复制代码
INSERT INTO prescription VALUES
(1, 2, 1, '2022-01-15'),
(2, 2, 1, '2023-01-10'),
(3, 1, 1, '2021-05-20'),
(4, 3, 1, '2023-03-15'),
(5, 4, 1, '2020-11-30');

3. 检查项目表(checkitem)

定义检查项目类型:

sql 复制代码
CREATE TABLE checkitem (
    checkItemID INT PRIMARY KEY,
    checkItemName VARCHAR(50)
);

示例数据

sql 复制代码
INSERT INTO checkitem VALUES
(1, '血常规'),
(2, '尿常规'),
(3, '心电图');

二、基础数学函数详解

1. ABS() - 绝对值

语法ABS(number)
示例

sql 复制代码
SELECT ABS(-10) AS result; -- 输出:10

2. CEIL()/CEILING() - 向上取整

语法CEIL(number)
示例

sql 复制代码
SELECT CEIL(4.3) AS result; -- 输出:5
SELECT CEIL(-4.3) AS result; -- 输出:-4

3. FLOOR() - 向下取整

语法FLOOR(number)
示例

sql 复制代码
SELECT FLOOR(4.7) AS result; -- 输出:4
SELECT FLOOR(-4.3) AS result; -- 输出:-5

4. ROUND() - 四舍五入

语法ROUND(number, decimal_places)
示例

sql 复制代码
SELECT ROUND(4.567, 2) AS result; -- 输出:4.57
SELECT ROUND(4.567, 0) AS result; -- 输出:5

三、子查询实战案例

1. 查找做过"血常规"检查的患者

sql 复制代码
SELECT p.patientName 
FROM patient p
WHERE p.patientID IN (
    SELECT pr.patientID 
    FROM prescription pr
    JOIN checkitem ci ON pr.checkItemID = ci.checkItemID
    WHERE ci.checkItemName = '血常规'
);

输出

sql 复制代码
patientName
夏颖
姚维新
张三
李四

2. 显示每个患者的检查次数

sql 复制代码
SELECT p.patientName, 
       (SELECT COUNT(*) 
        FROM prescription 
        WHERE patientID = p.patientID) AS check_count
FROM patient p;

输出

sql 复制代码
patientName | check_count
姚维新       | 1
夏颖        | 2
张三        | 1
李四        | 1
简要选       | 0

3. 查找2022年后做过检查的患者

sql 复制代码
SELECT p.patientName 
FROM patient p
WHERE EXISTS (
    SELECT 1 
    FROM prescription 
    WHERE patientID = p.patientID 
      AND examDate > '2022-12-31'
);

输出

sql 复制代码
patientName
夏颖
张三

4. 查找最近3年内做过检查的患者

sql 复制代码
SELECT p.patientName 
FROM patient p
WHERE EXISTS (
    SELECT 1 
    FROM prescription 
    WHERE patientID = p.patientID 
      AND examDate >= DATE_SUB(CURDATE(), INTERVAL 3 YEAR)
);

5. 计算患者年龄并筛选30-40岁之间的患者

sql 复制代码
SELECT patientName, 
       TIMESTAMPDIFF(YEAR, birthDate, CURDATE()) AS age
FROM patient
HAVING age BETWEEN 30 AND 40;

输出

sql 复制代码
patientName | age
姚维新       | 33
夏颖        | 38
简要选       | 43

6. 显示每个检查项目的使用次数

sql 复制代码
SELECT ci.checkItemName, 
       COUNT(pr.prescriptionID) AS usage_count
FROM checkitem ci
LEFT JOIN prescription pr ON ci.checkItemID = pr.checkItemID
GROUP BY ci.checkItemID;

输出

sql 复制代码
checkItemName | usage_count
血常规        | 5
尿常规        | 0
心电图        | 0

四、关键问题与优化建议

  1. 年龄计算的准确性

    • 使用TIMESTAMPDIFF(YEAR, birthDate, CURDATE())替代简单年份差,避免忽略月份和日期。

    • 示例:TIMESTAMPDIFF(YEAR, '1990-05-15', '2023-10-01') 精确计算为33岁。

  2. 子查询性能优化

    • 避免在WHERE子句中对字段使用函数(如YEAR(examDate)),改用范围查询:

      sql 复制代码
      WHERE examDate BETWEEN '2023-01-01' AND '2023-12-31'
相关推荐
20242817李臻1 小时前
20242817李臻-安全文件传输系统-项目验收
数据库·安全
行思理1 小时前
MongoDB慢查询临时开启方法讲解
数据库·mongodb
bbsh20991 小时前
WebFuture 升级提示“不能同时包含聚集KEY和大字段””的处理办法
数据库·sql·mysql·webfuture
霖檬ing1 小时前
Python——MySQL远程控制
开发语言·python·mysql
Zfox_5 小时前
Redis:Hash数据类型
服务器·数据库·redis·缓存·微服务·哈希算法
陈丹阳(滁州学院)7 小时前
若依添加添加监听容器配置(删除键,键过期)
数据库·oracle
远方16098 小时前
14-Oracle 23ai Vector Search 向量索引和混合索引-实操
数据库·ai·oracle
GUIQU.9 小时前
【Oracle】数据仓库
数据库·oracle
恰薯条的屑海鸥10 小时前
零基础在实践中学习网络安全-皮卡丘靶场(第十六期-SSRF模块)
数据库·学习·安全·web安全·渗透测试·网络安全学习
咖啡啡不加糖10 小时前
Redis大key产生、排查与优化实践
java·数据库·redis·后端·缓存