2010-10-28 48 views
3

考慮下面的示例表架構如何選擇多個連接表值符合選擇標準的行?

客戶表

CustID 
1 
2 
3 

發票表

CustID InvoiceID 

1  10 
1  20 
1  30 
2  10 
2  20 
3  10 
3  30 

的目標是選擇誰擁有的10和20的InvoiceID值(不是OR)的所有客戶。因此,在這個例子中,客戶w/CustID = 1和2將被退回。

你將如何構造SELECT語句?

回答

6

用途:

SELECT c.custid 
    FROM CUSTOMER c 
    JOIN INVOICE i ON i.custid = c.custid 
    WHERE i.invoiceid IN (10, 20) 
GROUP BY c.custid 
    HAVING COUNT(DISTINCT i.invoiceid) = 2 

關鍵的一點是,i.invoiceid計數需要等於IN子句中的參數個數。

使用的COUNT(DISTINCT i.invoiceid)是萬一有沒有客戶ID和invoiceid的組合,唯一約束 - 如果沒有重複的機會,你可以從查詢省略DISTINCT:

SELECT c.custid 
    FROM CUSTOMER c 
    JOIN INVOICE i ON i.custid = c.custid 
    WHERE i.invoiceid IN (10, 20) 
GROUP BY c.custid 
    HAVING COUNT(i.invoiceid) = 2 
+0

這將限制查詢結果給10和20的客戶。根據您的需要,留出具有條款以允許擁有10,20和額外發票的客戶。 – ulty4life 2010-10-28 21:38:32

+0

@ ulty4life:我不認爲你是對的。 WHERE子句將在COUNT之前過濾出所有其他InvoiceID記錄,只留下10和20的計數。 – Bill 2010-10-28 21:56:32

+0

@Bill - 你當然是對的,我會糾正的。 – ulty4life 2010-10-28 22:29:05

0
select CustID 
    from InvoiceTable 
    where InvoiceID in (10,20) 
    group by CustID 
    having COUNT(distinct InvoiceID) = 2 
1

Group By答案將工作,除非發票表中可能有多個CustID/InvoiceId。那你可能會得到一些意想不到的結果我更喜歡下面的答案,因爲它更接近您描述它的邏輯。

Select CustID 
From Customer 
Where 
    Exists (Select 1 from Invoice Where CustID=Customer.CustID and InvoiceID=10) 
and 
    Exists (Select 1 from Invoice Where CustID=Customer.CustID and InvoiceID=20) 
+0

您對重複的聲明不正確 - 請參閱我對使用COUNT和COUNT的評論(DISTINCT ...) – 2010-10-28 21:45:15