Sql 用于列出具有多个发票的客户的所有发票的查询

Sql 用于列出具有多个发票的客户的所有发票的查询,sql,sql-server,Sql,Sql Server,以下是两个表的简化版本: Invoice ======== InvoiceID CustomerID InvoiceDate TransactionDate InvoiceTotal Customer ========= CustomerID CustomerName 我想要的是所有发票的列表,其中每个客户有一个以上的发票。我不想对发票进行分组或计数,我实际上需要查看所有发票。输出如下所示: CustomerName TransactionDate InvoiceTotal --

以下是两个表的简化版本:

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编写查询以实现此目的的最佳方法是什么?

这应该可以:

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

使用窗口函数将使此操作非常简洁-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

良好的旧组,在子选择中使用in子句:

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
)

有趣的是——使用PARTITION BY来避免必须执行GROUP BY。我喜欢。你的EXISTS可能比我的NOT在解决方案中表现得更好。我对这方面的分析很感兴趣。如果我想在日期之前限制这一点呢?交易日期>=2013-01-01@planeBrad然后,您首先需要指定是否只需要该日期的副本,或者是否只想筛选该日期的当前结果(这些是不同的要求)。我想我已经解决了自己的问题。我刚刚将TransactionDate参数添加到WHERE语句中。