You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQL Server:在单个查询中获取最大与最小记录

获取Patient和Appointment表的最大/最小记录(SQL Server)

首先先确认下你提供的两张表结构,方便理解上下文:

CREATE TABLE Patient ( 
    patientID int, 
    firstName varchar(50) NOT NULL, 
    middleName varchar(50), 
    surName varchar(50) NOT NULL, 
    p_age int NOT NULL, 
    p_gender char(1), 
    p_address varchar(200), 
    p_contact_no int, 
    medicalHistory varchar(500), 
    allergies varchar(200), 
    CONSTRAINT PK_Patient PRIMARY KEY (patientID) 
);

CREATE TABLE Appointment ( 
    appID int, 
    patientId int, 
    staffId int, 
    appDateTime DateTime, 
    CONSTRAINT PK_Appointment PRIMARY KEY (appID), 
    CONSTRAINT FK_Appointment_Patient FOREIGN KEY (patientId) REFERENCES Patient(patientID) 
);

接下来分两种常见场景写单个查询,满足你的需求:

场景1:获取整体聚合的最大/最小值(统计类数值)

如果你只是需要统计范围类的数据,比如患者的年龄区间、预约时间的首尾范围,用下面的查询即可,它会返回一行包含所有聚合结果:

SELECT
    -- 患者年龄相关最值
    MAX(p.p_age) AS 最大患者年龄,
    MIN(p.p_age) AS 最小患者年龄,
    -- 预约时间相关最值
    MIN(a.appDateTime) AS 最早预约时间,
    MAX(a.appDateTime) AS 最晚预约时间
FROM Patient p
LEFT JOIN Appointment a ON p.patientID = a.patientId;

这里用LEFT JOIN是为了确保即使没有预约记录的患者也会被纳入年龄统计,如果只需要统计有预约的患者,换成INNER JOIN即可。

场景2:获取对应最值的完整记录(具体实体信息)

如果需要拿到具体的记录详情(比如最年长患者的姓名、地址,最早预约的患者和医护人员信息),可以用CTE(公共表表达式)+ 排序函数实现,单个查询返回所有目标记录:

WITH 患者年龄排序 AS (
    SELECT 
        patientID, firstName, surName, p_age, p_address,
        -- 按年龄从大到小排序,排名1就是最年长
        ROW_NUMBER() OVER(ORDER BY p_age DESC) AS 年龄降序排名,
        -- 按年龄从小到大排序,排名1就是最年轻
        ROW_NUMBER() OVER(ORDER BY p_age ASC) AS 年龄升序排名
    FROM Patient
),
预约时间排序 AS (
    SELECT 
        appID, patientId, staffId, appDateTime,
        -- 按时间从早到晚排序,排名1就是最早预约
        ROW_NUMBER() OVER(ORDER BY appDateTime ASC) AS 时间升序排名,
        -- 按时间从晚到早排序,排名1就是最晚预约
        ROW_NUMBER() OVER(ORDER BY appDateTime DESC) AS 时间降序排名
    FROM Appointment
)
-- 合并四类记录
SELECT
    '最年长患者' AS 记录类型,
    patientID AS 患者ID,
    CONCAT(firstName, ' ', surName) AS 患者姓名,
    p_age AS 年龄,
    p_address AS 地址,
    NULL AS 预约ID,
    NULL AS 医护人员ID,
    NULL AS 预约时间
FROM 患者年龄排序 WHERE 年龄降序排名 = 1
UNION ALL
SELECT
    '最年轻患者' AS 记录类型,
    patientID AS 患者ID,
    CONCAT(firstName, ' ', surName) AS 患者姓名,
    p_age AS 年龄,
    p_address AS 地址,
    NULL AS 预约ID,
    NULL AS 医护人员ID,
    NULL AS 预约时间
FROM 患者年龄排序 WHERE 年龄升序排名 = 1
UNION ALL
SELECT
    '最早预约' AS 记录类型,
    p.patientID AS 患者ID,
    CONCAT(p.firstName, ' ', p.surName) AS 患者姓名,
    NULL AS 年龄,
    NULL AS 地址,
    a.appID AS 预约ID,
    a.staffId AS 医护人员ID,
    CONVERT(VARCHAR, a.appDateTime, 120) AS 预约时间
FROM 预约时间排序 a
JOIN Patient p ON a.patientId = p.patientID
WHERE a.时间升序排名 = 1
UNION ALL
SELECT
    '最晚预约' AS 记录类型,
    p.patientID AS 患者ID,
    CONCAT(p.firstName, ' ', p.surName) AS 患者姓名,
    NULL AS 年龄,
    NULL AS 地址,
    a.appID AS 预约ID,
    a.staffId AS 医护人员ID,
    CONVERT(VARCHAR, a.appDateTime, 120) AS 预约时间
FROM 预约时间排序 a
JOIN Patient p ON a.patientId = p.patientID
WHERE a.时间降序排名 = 1;

小提示

如果存在多个并列的最值(比如有两个患者都是20岁,同为最年轻),上面的查询只会返回其中一条。如果需要返回所有并列记录,把ROW_NUMBER()换成RANK()即可。

内容的提问来源于stack exchange,提问作者u_u-de

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:15:48