首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

MySQL 兩表關聯查詢:LEFT JOIN 獲取寶寶所有疫苗狀態(含未接種)

     編輯:程式設計綜合問答

表結構假設

-- 寶寶信息表 (已接種記錄)
CREATE TABLE baby_vaccine_record (
    id INT PRIMARY KEY AUTO_INCREMENT,
    baby_id INT NOT NULL,
    vaccine_id INT NOT NULL,
    is_vaccined TINYINT DEFAULT 1, -- 1=已接種
    vaccined_date DATE,
    INDEX idx_baby (baby_id)
);

-- 疫苗基礎信息表 (所有疫苗)
CREATE TABLE vaccine_info (
    vaccine_id INT PRIMARY KEY,
    vaccine_name VARCHAR(100),
    vaccine_type VARCHAR(50),
    recommended_age VARCHAR(50)
);

目標:查詢指定寶寶的所有疫苗狀態

結果需包含:疫苗名稱、類型、推薦年齡、**是否已接種 (是/否)**、接種日期 (未接種為 NULL)。

標準 SQL (LEFT JOIN)

SELECT 
    vi.vaccine_id,
    vi.vaccine_name,
    vi.vaccine_type,
    vi.recommended_age,
    CASE WHEN bvr.is_vaccined = 1 THEN '已接種' ELSE '未接種' END AS status,
    bvr.vaccined_date
FROM vaccine_info vi
LEFT JOIN baby_vaccine_record bvr
    ON vi.vaccine_id = bvr.vaccine_id
   AND bvr.baby_id = 12345  -- 目標寶寶 ID
ORDER BY vi.recommended_age; -- 或按 vaccine_id 排序

關鍵點解析

技術點說明
LEFT JOIN 保留左表 (vaccine_info) 所有行,右表無匹配則列為 NULL → 實現「未接種也顯示」。
ON 條件含 baby_id 將過濾條件放在 ON 而非 WHERE,否則會過濾掉未接種行 (因 bvr.baby_id 為 NULL)。
CASE WHEN 將 0/1 轉為可讀狀態文本。
索引優化 baby_vaccine_record(baby_id, vaccine_id) 聯合索引加速 JOIN。

等效子查詢寫法 (性能通常較差)

SELECT 
    vi.*,
    (SELECT '已接種' FROM baby_vaccine_record bvr 
     WHERE bvr.vaccine_id = vi.vaccine_id AND bvr.baby_id = 12345 AND bvr.is_vaccined = 1
     LIMIT 1) AS status,
    (SELECT vaccined_date FROM baby_vaccine_record bvr 
     WHERE bvr.vaccine_id = vi.vaccine_id AND bvr.baby_id = 12345
     LIMIT 1) AS vaccined_date
FROM vaccine_info vi;

Java/MyBatis 映射示例

<select id="selectVaccineStatusByBabyId" resultType="VaccineStatusVO">
    SELECT vi.vaccine_id, vi.vaccine_name, vi.vaccine_type, vi.recommended_age,
           CASE WHEN bvr.is_vaccined = 1 THEN '已接種' ELSE '未接種' END AS status,
           bvr.vaccined_date
    FROM vaccine_info vi
    LEFT JOIN baby_vaccine_record bvr
        ON vi.vaccine_id = bvr.vaccine_id
       AND bvr.baby_id = #{babyId}
    ORDER BY vi.vaccine_id
</select>

常見錯誤

用 INNER JOIN
只返回已接種疫苗,丟失未接種信息。
WHERE bvr.baby_id = 12345
同 INNER JOIN 效果,因 NULL 不等於任何值。
未處理重複接種記錄
若同一疫苗有多條記錄,需在 JOIN 前去重或聚合 (如取最新日期)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved