2013-11-22 44 views
1

下面是這兩個表的簡化版本:查詢列出客戶的所有發票與多個

Invoice 
======== 
InvoiceID 
CustomerID 
InvoiceDate 
TransactionDate 
InvoiceTotal 

Customer 
========= 
CustomerID 
CustomerName 

我想是所有發票那裏是每個客戶一個以上的列表。我不想對發票進行分組或計數,實際上我需要查看所有發票。輸出會是這個樣子:

CustomerName TransactionDate InvoiceTotal 
------------------------------------------------- 
Ted Tester  2012-12-14   335.49 
Ted Tester  2013-02-02   602.00 
Bob Beta  2013-05-04   779.50 
Bob Beta  2013-07-07   69.00 
Bob Beta  2013-09-10   849.79 

什麼是寫爲SQL Server查詢來實現這一點的最佳方式是什麼?

回答

1

這應該這樣做:

SELECT C.CustomerName, 
     I.TransactionDate, 
     I.InvoiceTotal 
FROM dbo.Invoice I 
INNER JOIN dbo.Customer C 
    ON I.CustomerID = C.CustomerID 
WHERE EXISTS(SELECT 1 FROM Invoice 
      WHERE CustomerID = I.CustomerID 
      GROUP BY CustomerID 
      HAVING COUNT(*) > 1) 

而另一種方式爲SQL Server 2005+:

;WITH CTE AS 
(
    SELECT C.CustomerName, 
      I.TransactionDate, 
      I.InvoiceTotal, 
      N = COUNT(*) OVER(PARTITION BY I.CustomerID) 
    FROM dbo.Invoice I 
    INNER JOIN dbo.Customer C 
     ON I.CustomerID = C.CustomerID 
) 
SELECT * 
FROM CTE 
WHERE N > 1 
+0

你EXISTS可能表現得比我NOT IN更好的解決方案。我會對這個分析感興趣。 –

+0

如果我想按日期限制這個,該怎麼辦? TransactionDate> = 2013-01-01 – planeBrad

+0

@planeBrad那麼你首先需要指定,如果你想只爲在該日期或重複,如果你只是想過濾出日期目前的結果(這些都是不同的要求) – Lamak

2

使用窗口功能將使這個很乾淨的事 - 這會由SQL Server支持2005年和更大:

SELECT CustomerName, TransactionDate, InvoiceTotal 
FROM (
    SELECT c.CustomerName, i.TransactionDate, i.InvoiceTotal, 
     COUNT(*) OVER (PARTITION BY i.CustomerId) as InvoiceCount 
    FROM Invoice i 
    JOIN Customer c ON i.CustomerId = c.CustomerId 
) t 
WHERE InvoiceCount > 1 
+0

有趣 - 使用PARTITION BY來避免必須執行GROUP BY。我喜歡。 –

+0

@DavidFleeman:這就是爲什麼它在那裏:) – PinnyM

0

好老GROUP BY使用IN子句中子查詢HAVING:

SELECT c2.CustomerName, i2.TransactionDate, i2.InvoiceTotal 
FROM Invoice i2 
    INNER JOIN Customer c2 ON i2.CustomerID = c2.CustomerID 
WHERE i2.CustomerID IN (
    SELECT c.CustomerID 
    FROM Customer c 
     INNER JOIN Invoice i on i.CustomerID = c.CustomerID 
    GROUP BY c.CustomerID 
    HAVING COUNT(i.InvoiceID) > 1 
)