首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL 子查詢實戰教學:IN、NOT IN、EXISTS 與聚合函數在子查詢中的進階應用

     編輯:關於SqlServer

子查詢核心價值

將一個 SELECT 嵌入另一個查詢,將結果集比較邏輯下推至資料庫引擎,避免應用層撈回大量資料再比對,提升效能與簡潔度。

場景一:IN 子查詢 - 篩選符合條件的子集

-- 找出 Metallica 專輯中歌詞包含 'justice' 的歌曲
SELECT song_name FROM Album
WHERE band_name = 'Metallica'
  AND song_name IN (
      SELECT song_name FROM Lyric
      WHERE song_lyric LIKE '%justice%'
  );
  • 外層查詢 Album,內層 Lyric 提供歌曲名單集合。
  • IN 子查詢結果集作為外層 WHERE 篩選條件。
  • 不需輸出 Lyric 欄位,僅作為條件來源。

場景二:NOT IN 子查詢 - 排除符合條件的子集

-- 找出 'And Justice for All' 專輯中歌詞「不含」 justice 的歌曲
SELECT song_name FROM Album
WHERE album_name = 'And Justice for All'
  AND band_name = 'Metallica'
  AND song_name NOT IN (
      SELECT song_name FROM Lyric
      WHERE song_lyric LIKE '%justice%'
  );
  • 邏輯互補:回傳外層結果集中 不在 內層結果集的列。
  • 注意:若內層結果集含 NULL,NOT IN 將回傳空集合,建議改用 NOT EXISTS。

場景三:EXISTS 相關子查詢 - 逐列驗證關聯存在性

-- 找出 Metallica 原唱且被 Damage, Inc. 翻唱的歌曲
SELECT Album.song_name FROM Album
WHERE Album.band_name = 'Metallica'
  AND EXISTS (
      SELECT 1 FROM Cover
      WHERE Cover.band_name = 'Damage, Inc.'
        AND Cover.song_name = Album.song_name
  );
  • EXISTS 只檢查 是否至少存在一列,不回傳實際資料,效能通常優於 IN (尤其內層大量資料時)。
  • 為相關子查詢:內層參考外層資料表別名 (Album.song_name),每列外層資料各執行一次內層查詢。
  • 需使用完整欄位前綴 (Album.song_name, Cover.song_name) 避免歧義。

場景四:聚合函數在子查詢中 - 統計驗證

-- 找出專輯實際收錄曲數與資料庫記錄曲數不符的專輯
SELECT AlbumInfo.album_name FROM AlbumInfo
WHERE AlbumInfo.band_name = 'Metallica'
  AND AlbumInfo.album_tracks <> (
      SELECT COUNT(*) FROM Album
      WHERE Album.band_name = AlbumInfo.band_name
        AND Album.album_name = AlbumInfo.album_name
  );
  • 內層 COUNT(*) 計算實際歌曲數,與外層中繼資料欄位 album_tracks 比對。
  • 適用於資料品質稽核、彙總驗證、異常偵測。

效能與寫法建議

建議理由
優先使用 EXISTS 代替 IN (大量內層資料)EXISTS 可短路停止掃描,IN 需完整建立結果集
避免 NOT IN 含 NULL 風險改用 NOT EXISTS 或 LEFT JOIN ... WHERE right.key IS NULL
相關子查詢確保內層有索引支援如 Cover(song_name, band_name) 複合索引
可轉為 JOIN 重寫時優先考慮現代優化器常能自動轉換,但明確 JOIN 更易閱讀維護
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved