2013-05-06 121 views
0

我真的停留在這個問題上。我需要創建一個查詢,其中有一個包含CustomerID和PurchaseID號碼的表。在另一張表中,我有CustomerID以及客戶的名字和姓氏。我需要做的是隻獲取記錄有PurchaseID爲1或2或7的客戶的姓氏和名字。當我嘗試我的代碼時,我從第二個tabel(包含FirstName,LastName,和CustomerID),這是不正確的。比較表格信息從另一個

這是我的代碼:

SELECT FirstName, LastName 
    FROM Customer, Purchase 
WHERE Purchase.PurchaseID = '1' 
    OR Purchase.PurchaseID = '2' 
    OR Purchase.PurchaseID = '7' 
GROUP BY FirstName, LastName; 

我很新的SQL,並會真的在這裏感謝幫助。

+0

Customer,Purchase表之間的關係是什麼? – KuldipMCA 2013-05-06 07:14:38

回答

2
SELECT DISTINCT c.FirstName, c.LastName 
FROM Customer c 
JOIN Purchase p ON p.CustomerID = c.CustomerID 
WHERE p.PurchaseID IN ('1', '2', '7') 
ORDER BY c.LastName, c.FirstName 

UPDATE:爲了響應@大衛阿爾德里奇的意見,我只是測試的SQL Server 2008 R2與最新的服務包兩種形式(他和我的)。並且它們生成成本執行計劃IDENTICAL。實際上,我的連接形式的邏輯讀取次數略低(但當然可能隨實際ID的選擇而變化)

我對SQL Server示例數據庫AdventureWorksDW2008運行了這兩個查詢(因爲David提到「我曾在數據倉庫」):

select distinct c.FirstName, c.LastName 
from dbo.FactInternetSales s 
join dbo.DimCustomer c on c.CustomerKey = s.CustomerKey 
where s.ProductKey IN (328, 333, 472) 

SELECT FirstName, 
     LastName 
FROM dbo.DimCustomer c 
where exists (
     select null 
     from dbo.FactInternetSales s 
     WHERE s.CustomerKey = c.CustomerKey and 
       s.ProductKey in (328, 333, 472)) 
+0

如果回答中不需要購買記錄詳細信息,那麼簡單的加入可能效率非常低,除非優化程序認識到,排除購買列和包含distinct後,允許查詢在發現單個匹配產品時暫停每個客戶。我不認爲它會。 – 2013-05-06 07:25:15

+0

優化器非常好。我更喜歡讓它做它的設計...... – 2013-05-06 07:26:21

+0

它肯定是,但它也很容易測試它是否實際上做了轉型。這個查詢的效率可能非常低,我認爲編寫一個語義正確的查詢通常會更好,因爲它不會太依賴於優化器。對不起,但我必須投票否決,因爲我已經在數據倉庫工作,與基於存在的方法相比,這將會非常低效。 – 2013-05-06 07:31:20

-1

的另一種方式,去無IN

SELECT DISTINCT c.FirstName, c.LastName 
FROM Customer c 
JOIN Purchase p ON p.CustomerID = c.CustomerID 
WHERE 
p.PurchaseID = '1' OR p.PurchaseID = '2' 
OR p.PurchaseID = '7' 
ORDER BY c.LastName, c.FirstName 
0

育有基本都加入。你試圖做的是JOIN舊的ANSI SQL-89語法。但不建議這樣做。

SELECT FirstName, LastName 
FROM Customer, Purchase 
WHERE Customer.CustomerID = Purchase.CustomerID 
AND (Purchase.PurchaseID = '1' OR Purchase.PurchaseID = '2' 
OR Purchase.PurchaseID = '7') 

正確的方法做的是在Mitchwheat提到回答

1

嘗試此查詢:

SELECT C.FirstName, C.LastName 
    FROM Customer C 
    JOIN Purchase P ON P.CustomerID = C.CustomerID 
WHERE P.PurchaseID IN ('1','2','7') 
GROUP BY C.FirstName, C.LastName 

入住這SQL Fiddle test code以防萬一,以確保它的工作原理。相同的客戶添加了幾個購買,以確保不會重複的結果。感謝David Aldridge指出了這一點。

還有另外一種選擇,使用EXISTS作爲David提出的答案。如果你有大桌子可以工作,應該更有效率。使用該選項檢查此其他SQL Fiddle test code。使用舊的ANSI-89 JOIN語法

避免使用JOIN更好的可讀性:

FROM Customer, Purchase 
WHERE Purchase.PurchaseID = '1' 

檢查Aaron Bertrands blog有關它的更多信息

+1

這不會爲每個客戶購買他們購買的這些類型的產品返回一行嗎? – 2013-05-06 07:22:24

+0

如果你添加一個GROUP BY,它應該修復所有彈出的冗餘名稱。 – bloodstorm17 2013-05-06 07:24:26

+1

雖然這不會在語義上正確。不同的會更接近,但查詢會查找客戶購買的所有匹配產品的完整列表,然後基本丟棄它們。可能非常低效。 – 2013-05-06 07:27:23

0

如果你想檢查是否存在購買的各種產品對於客戶,則使用:

SELECT FirstName, 
     LastName 
FROM Customer 
where exists (
     select null 
     from Purchase 
     WHERE Purchase.customerID = customer.customerid and 
       Purchase.PurchaseID in ('1','2','7')) 

優化器只需要在購買表中找到一行就可以知道客戶是 被包括。

+0

Yeap,它的工作原理,我不知道爲什麼downvote。這裏是[sql小提琴測試](http://sqlfiddle.com/#!3/ab3bd/4) – Yaroslav 2013-05-06 07:40:32

+0

乾杯。關於downvote,呃我不親自帶他們。 – 2013-05-06 09:11:12