2014-12-22 52 views
0

這聽起來很愚蠢。SQL根據條件忽略行

所以2臺訂單和訂單明細

ORDER_ID  ITEM_NAME 
========  ========= 
111   Paper 
111   Toner 
222   Paper 
333   Pencils 

我想查詢只有Order_ID上的人的ITEM_NAME是紙

所以比如我的查詢唯一的結果應該是

ORDER_ID  ITEM_NAME 
========  ========= 
222   Paper 

我不不想要ORDER_ID與其他項目有關。我只希望ORDERID是唯一的ITEM_Name是Paper。

+0

尼爾,每次你編輯問題時,你似乎都會讓格式變得更糟! :-)然後你去承擔把表移動到外部圖像站點的罪過。您應該將其保留在此處,以便SO保持有用,無論其他網站發生什麼情況。我已將它格式化爲您的規格。 – paxdiablo

回答

0
SELECT OrderDetails.* 
FROM OrderDetails 
WHERE ITEM_Name = 'Paper' 
AND Order_ID NOT IN (SELECT Order_ID FROM OrderDetails WHERE ITEM_Name <> 'Paper') 

在這一個,你選擇所有項目,其中item_name ='紙'。然後排除所有的訂單,他們有一條線,<>「紙」

候補:

如果我們可以假設ITEM_NAME是(至少在MS SQL Server)的每個訂單的唯一的,那麼你可以這樣做:

;with NumberOfRows as 
(
    SELECT COUNT(1) as TotalRows, Order_ID 
    FROM OrderDetails 
    GROUP BY Order_ID 
) 
SELECT OrderDetails.* 
FROM OrderDetails 
INNER JOIN NumberOfRows 
ON NumberOfRows.Order_ID = OrderDetails.OrderID 
AND NumberOfRows.TotalRows = 1 
WHERE OrderDetails.Item_Name = 'Paper' 

作爲另一種選擇:

select OrderDetails1.* 
from OrderDetails as OrderDetails1 
LEFT JOIN OrderDetails OrderDetails2 
ON OrderDetails1.Order_ID = OrderDetails2.Order_ID 
AND OrderDetails2.ITEM_Name <> 'Paper' 
Where ITEM_Name = 'Paper' 
AND OrderDetails2.Order_ID IS NULL 

在這最後一個,你得到所有日e訂單並且回到他們自己的第二行不是紙的地方。然後排除加入成功的所有訂單。如果訂單明細表具有獨特的內容(如行ID),這將更容易理解。

0

如果你想訂購是只有紙ID,我會建議使用group byhaving條款:

select od.Order_Id 
from OrderDetails od 
group by od.Order_Id 
having sum(case when od.Item_Name = 'Paper' then 1 else 0 end) > 0 and 
     sum(case when od.Item_Name <> 'Paper' then 1 else 0 end) = 0 

having子句兩個條件。第一個計數具有Paper作爲項目的訂單的行數。 > 0表示至少需要一個。第二個計算沒有紙張的行數。 = 0表示不需要。

這也可以寫成:

having sum(case when od.Item_Name = 'Paper' then 1 else 0 end) = count(*) 

即所有項目的順序是「紙」。

我喜歡這種方法,因爲它非常一般。你可以很容易地將它擴展到包括剪刀和岩石。或者得到有紙但沒有石頭的訂單等等。