2016-06-25 81 views
0

我正在使用TransactSQL(Microsoft SQL Server 2014),這裏是我的問題: 我正在使用標準的「Northwind」數據庫進行練習,我希望看到一個類別列表,沒有任何產品。IN中的子查詢不起作用

首先我創建了一個新的類別,這不會有任何產品:

insert into Categories (CategoryName) values ('TestCategory') 

然後我寫了這個:

SELECT CategoryName 
    FROM Categories 
    WHERE CategoryID NOT IN (select CategoryID from Products) 

不幸的是它給了什麼。

我是這樣理解:
我想找到的類別,在與其沒有連接的產品,所以我用 WHERE CategoryID NOT IN (select CategoryID from Products),因爲我想每一個類別ID從分類表的清單,我從select CategoryID from Products得到比較 - 這個名單包括HAS產品的每個類別。所以我認爲使用NOT IN應該讓我看到沒有任何產品的類別。

我希望你明白我想描述的是什麼。如果你能提供幫助,那會很好。

+0

你能確認你的'TestCategory'是否真的存在嗎? (即你的插入語句承諾)? – Gerrat

+0

是的,它肯定是,下面的答案解決了這個問題 – Loreno

回答

2

NOT IN是不是一個好的結構。如果來自子查詢的任何返回值是NULL,那麼它永遠不會返回任何行。解決這個問題一個天真的方法是使用WHERE

SELECT CategoryName 
FROM Categories 
WHERE CategoryID NOT IN (select CategoryID from Products where CategoryId IS NOT NULL); 

一個更好的辦法來解決它是使用NOT EXISTS

SELECT c.CategoryName 
FROM Categories c 
WHERE NOT EXISTS (SELECT 1 
        FROM Products p 
        WHERE p.CategoryID = c.CategoryID 
       ); 

此行爲以更直觀的方式。

請注意,此行爲是ANSI標準行爲。當存在NULL值時,則引擎不知道c.categoryId是否在列表中。因此,它返回NULL,將其視爲false。

2

的Sql工作三個值基於logic.Your表必須包含在類ID空列那爲什麼它不顯示任何內容,修改子查詢作爲

SELECT CategoryName 
    FROM Categories 
    WHERE CategoryID NOT IN (select CategoryID from Products where catogoryID is not null) 
0

我還發現了另一種解決方案:

select CategoryName from Categories c LEFT OUTER JOIN Products p 
ON c.CategoryID = p.CategoryID 
where ProductName is null 

我認爲以上的回答是更直觀,但我只是想顯示的處理這個法子。