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语句中。