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

MySQL多表关联查询:获取人员全信息及对应证书有效期

人员证书信息的SQL实现方案

完全可以通过SQL直接实现需求,无需借助PHP多查询组合。以下是具体的实现方式:

静态证书类型的SQL写法(适合证书类型固定的场景)

如果证书类型不会动态新增,直接使用条件聚合配合交叉连接即可:

SELECT
    p.id,
    p.Name,
    p.DoB,
    COALESCE(MAX(CASE WHEN ct.certification_name = 'Certification 1' THEN c.Expiration END), 'n/a') AS `Certification 1`,
    COALESCE(MAX(CASE WHEN ct.certification_name = 'Certification 2' THEN c.Expiration END), 'n/a') AS `Certification 2`
FROM
    People p
CROSS JOIN
    `Certification Types` ct
LEFT JOIN
    Certifications c ON p.id = c.person_id AND ct.id = c.certification_id
GROUP BY
    p.id, p.Name, p.DoB
ORDER BY
    p.id;

逻辑说明

  1. CROSS JOIN:生成所有人员与所有证书类型的组合,确保每个人员都能覆盖到所有证书类型;
  2. LEFT JOIN:关联证书表,保留所有人员+证书类型的组合,无对应证书的行Expiration字段会为NULL;
  3. 条件聚合:通过CASE WHEN匹配证书类型,用MAX提取对应有效期(分组后单条记录取自身值即可),再用COALESCE将NULL替换为n/a;
  4. GROUP BY:按人员唯一标识及基础信息分组,将同一人员的多条证书类型记录合并为一行。

动态证书类型的SQL写法(适合证书类型会新增的场景)

如果证书类型可能动态增加,可使用动态SQL自动生成列:

SET @sql = NULL;
SELECT
    GROUP_CONCAT(DISTINCT
        CONCAT(
            'COALESCE(MAX(CASE WHEN ct.certification_name = ''',
            certification_name,
            ''' THEN c.Expiration END), ''n/a'') AS `',
            certification_name,
            '`'
        )
    ) INTO @sql
FROM `Certification Types`;

SET @sql = CONCAT('SELECT p.id, p.Name, p.DoB, ', @sql, ' FROM People p CROSS JOIN `Certification Types` ct LEFT JOIN Certifications c ON p.id = c.person_id AND ct.id = c.certification_id GROUP BY p.id, p.Name, p.DoB ORDER BY p.id');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

逻辑说明

  1. 先从证书类型表中动态生成每个证书对应的列表达式;
  2. 拼接完整的查询SQL并执行,实现自动适配新增的证书类型。

以上两种写法都能直接输出你期望的格式,无需在PHP中做额外的数据拼接处理。

内容的提问来源于stack exchange,提问作者beaklessChicken

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 17:17:43