在 PostgreSQL 中,若需顯示 不在 IN
子句列表中的數據,可以通過以下方法實現:
方法 1:使用 NOT IN
(注意 NULL 值)
直接篩選不包含在 IN
列表中的記錄:
SELECT *
FROM your_table
WHERE your_column NOT IN (value1, value2, ...);
注意:若列表或列中存在 NULL
,NOT IN
可能返回意外結果。此時建議改用 NOT EXISTS
或 LEFT JOIN
。
方法 2:使用 LEFT JOIN
結合臨時表
將 IN
列表轉換為臨時表,并通過左連接找出缺失項:
WITH values_list (value) AS (VALUES (value1), (value2), (value3) -- 替換為你的具體值
)
SELECT vl.value AS missing_value
FROM values_list vl
LEFT JOIN your_table yt ON vl.value = yt.your_column
WHERE yt.your_column IS NULL;
效果:顯示所有在列表中但不在表中的值。
方法 3:使用 EXCEPT
集合操作符
直接對比兩個集合的差集:
(SELECT value FROM (VALUES (value1), (value2), ...) AS t(value)) -- 替換為你的列表
EXCEPT
SELECT your_column FROM your_table);
結果:返回列表中存在但表中不存在的值。
方法 4:動態生成完整列表并標記存在狀態
若需同時顯示存在與不存在的數據,并標記狀態:
WITH desired_values (value) AS (VALUES (value1), (value2), (value3) -- 你的目標值列表
)
SELECT dv.value,CASE WHEN yt.your_column IS NULL THEN '不存在' ELSE '存在' END AS status
FROM desired_values dv
LEFT JOIN your_table yt ON dv.value = yt.your_column;
輸出:每個值附帶狀態,清晰展示是否存在于表中。
示例場景
假設表 products
中有 product_id
,想檢查 (101, 102, 103)
是否存在:
WITH check_ids (id) AS (VALUES (101), (102), (103)
)
SELECT ci.id AS target_id,p.product_name,CASE WHEN p.product_id IS NULL THEN '缺失' ELSE '存在' END AS status
FROM check_ids ci
LEFT JOIN products p ON ci.id = p.product_id;
結果:列出每個目標 ID 及其存在狀態。
關鍵點
- 處理 NULL:當列或列表含 NULL 時,優先使用
LEFT JOIN
或NOT EXISTS
避免邏輯錯誤。 - 靈活轉換列表:通過
VALUES
或臨時表將硬編碼列表轉換為可連接的數據源。 - 明確需求:根據是否需要“反向篩選”或“完整對比”選擇合適方法。
根據具體場景選擇最適合的方案,確保數據對比的準確性和效率。