2010-10-28 85 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