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

SQL 子查詢實戰指南:IN、NOT IN、EXISTS 與彙總函數進階應用

     編輯:關於SqlServer

曾為取得所需資訊而反覆執行多次查詢?子查詢 (Subquery/Subselect) 讓您在單一陳述式中完成資料關聯、過濾與彙總比較。本文透過實務範例詳細說明四大核心用法。

核心概念:在結果集中搜尋

子查詢本質是「查詢中的查詢」——內層查詢產生的結果集成為外層查詢的資源。這將資料比對邏輯下推至資料庫引擎,避免應用層搬運資料比對。

用法一: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%'
  );

解析:

  1. 外層查詢:選出 Metallica 所有歌曲
  2. 內層查詢:從 Lyric 表找出歌詞含 "justice" 的歌曲
  3. IN 將內層結果集作為外層過濾條件
  4. 最終僅回傳同時符合兩條件的歌名

關鍵點:子查詢為獨立單元,無需使用完整欄位名 (如 Album.song_name);若需同時輸出歌詞,請改用 JOIN。

用法二: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%'
  );

邏輯為:專輯歌曲集合 減去 含 justice 歌曲集合 = 目標結果。單一陳述式取代應用層陣列比對。

用法三:EXISTS — 關聯兩個獨立查詢路徑的結果

情境:同時從 Album 表 (原唱) 與 Cover 表 (翻唱團體 Damage, Inc.) 找出同名歌曲。

SELECT Album.song_name FROM Album
WHERE Album.band_name = 'Metallica'
  AND EXISTS (
      SELECT Cover.song_name FROM Cover
      WHERE Cover.band_name = 'Damage, Inc.'
        AND Cover.song_name = Album.song_name
  );

差異於 IN:此處直接比對兩表欄位 (Cover.song_name = Album.song_name),故需使用完整欄位名稱。EXISTS 僅檢查「是否存在至少一筆」,不回傳實際資料,效能通常優於 IN。部分資料庫支援 NOT EXISTS。

用法四:彙總函數於子查詢中 — 數值比較驗證

情境:驗證 Album 表中每張專輯的歌曲數是否與 AlbumInfo 表記錄的 album_tracks 一致,並找出缺漏的專輯。

SELECT album_name FROM AlbumInfo a
WHERE album_tracks <> (
    SELECT COUNT(*) FROM Album
    WHERE Album.album_name = a.album_name
);

子查詢動態計算實際歌曲數,外層與預期值比對。此模式常用於資料品質檢核、對帳報表。

效能與最佳實務提醒

場景建議
子查詢結果集極大改用 JOIN 或 EXISTS,避免物質化大量中間結果
相關子查詢逐列執行確認有適當索引支援連接欄位
NOT IN 含 NULL 值小心!NOT IN (..., NULL) 永遠回傳 FALSE,改用 NOT EXISTS
重複使用相同子查詢考慮 CTE (WITH 子句) 或暫存表

小結

子查詢是 SQL 表達複雜業務邏輯的利器:IN 適合集合包含檢查,NOT IN 用於排除 (注意 NULL 陷阱),EXISTS 專為存在性驗證優化,彙總函數則能在單一查詢中完成跨層級數值比對。善用它們,能大幅簡化應用程式碼並提升效能。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved