2013-11-27 60 views
1

我有一個表「person」,一個關聯表「person_vaccination」和一個表「vaccination」。SQL - 選擇什麼不在聯合的第二個表中

我想讓失去疫苗的人失望,但到目前爲止,只有當我擁有身份證的時候,我才能得到它。

SELECT vac.VACCINATION_Name 
FROM VACCINATION vac 
WHERE vac.VACCINATION_NUMBER NOT IN 
(SELECT v.VACCINATION_NUMBER 
FROM PERSON per 
Join PERSON_VACCINATION pv ON per.PERSON_NUMBER = pv.PERSON_NUMBER 
JOIN VACCINATION v ON pv.VACCINATION_NUMBER = v.VACCINATION_NUMBER 
WHERE per.PERSON_NUMBER = 6) 

它工作正常,但我如何得到所有的人失蹤了接種疫苗? (例如: 555,Vacccination 1 555,Vacccination 2 666,Vacccination 1)

+0

1)將'IN(...)'子句重寫爲'EXISTS(...)'子句。 2)改變存在_not_存在。 3)利潤! – wildplasser

+0

您是否在尋找沒有接種疫苗的人,或是缺少特定疫苗的人? –

回答

2

SQL Fiddle

的Oracle 11g R2架構設置

CREATE TABLE VACCINATION (VACCINATION_NUMBER, VACCINATION_NAME) AS 
      SELECT 1, 'Vac 1' FROM DUAL 
UNION ALL SELECT 2, 'Vac 2' FROM DUAL 
UNION ALL SELECT 3, 'Vac 3' FROM DUAL 
UNION ALL SELECT 4, 'Vac 4' FROM DUAL; 

CREATE TABLE PERSON_VACCINATION (VACCINATION_NUMBER, PERSON_NUMBER) AS 
      SELECT 1, 1 FROM DUAL 
UNION ALL SELECT 2, 1 FROM DUAL 
UNION ALL SELECT 3, 1 FROM DUAL 
UNION ALL SELECT 4, 1 FROM DUAL 
UNION ALL SELECT 1, 2 FROM DUAL 
UNION ALL SELECT 2, 2 FROM DUAL 
UNION ALL SELECT 3, 2 FROM DUAL; 

CREATE TABLE PERSON (PERSON_NUMBER, PERSON_NAME) AS 
      SELECT 1, 'P1' FROM DUAL 
UNION ALL SELECT 2, 'P2' FROM DUAL 
UNION ALL SELECT 3, 'P3' FROM DUAL; 

查詢1

SELECT p.PERSON_NAME, 
     v.VACCINATION_NAME 
FROM VACCINATION v 
     CROSS JOIN 
     PERSON p 
WHERE NOT EXISTS (SELECT 1 
        FROM PERSON_VACCINATION pv 
        WHERE pv.VACCINATION_NUMBER = v.VACCINATION_NUMBER 
        AND pv.PERSON_NUMBER = p.PERSON_NUMBER) 
ORDER BY p.PERSON_NAME, 
     p.PERSON_NUMBER, 
     v.VACCINATION_NAME, 
     v.VACCINATION_NUMBER 

Results

| PERSON_NAME | VACCINATION_NAME | 
|-------------|------------------| 
|   P2 |   Vac 4 | 
|   P3 |   Vac 1 | 
|   P3 |   Vac 2 | 
|   P3 |   Vac 3 | 
|   P3 |   Vac 4 | 
+0

優秀!短而甜,謝謝! – user3043748

+0

你打我一樣的答案=) – Kairan

0

如果你是後人們沒有接種疫苗的話,那麼你可以使用LEFT OUTER PERSON和PERSON_VACCINATION之間的連接,然後找到的所有條目,其中一個PERSON_VACCINATION列爲NULL。

SELECT PERSON_NUMBER 
FROM PERSON P 
LEFT OUTER JOIN 
PERSON_VACCINATION PV 
ON P.PERSON_NUMBER = PV.PERSON_NUMBER 
WHERE PV.PERSON_NUMBER IS NULL 

如果你不熟悉LEFT OUTER JOIN,它試圖找到PERSON_VACCINATION匹配的行爲親自每一行。如果沒有匹配的行,則它將PERSON行留在結果集中,併爲PERSON_VACCINATION表中的所有列顯示NULL值。

如果您正在尋找他們沒有的人員列表和疫苗接種,那麼@MT0的答案是正確的。您需要創建一個包含PERSON和VACCINATION(一個交叉連接)的所有可能組合的結果集,然後檢查PERSON_VACCINATION中實際存在哪些組合。任何不存在的條目都是你缺少的疫苗接種。

相關問題