我有一个像这样的表结构:
Order Table
OrderId int
OrderValue decimal
Payment Table
PaymentId int
OrderId int
PaymentAmount decimal
PaymentDate datetime
订单可以有很多付款。我需要找到哪个是按日期排序的第一笔付款,当添加到之前的付款时,大于或等于订单价值。
所以,如果我有以下内容:
| OrderId | OrderValue |
| 1 | 1000 |
| PaymentId | OrderId | PaymentAmount | PaymentDate |
| 1 | 1 | 100 | 2014-02-01 |
| 2 | 1 | 500 | 2014-02-02 |
| 3 | 1 | 400 | 2014-02-03 |
| 4 | 1 | 100 | 2014-02-04 |
在创建PaymentId 3时,OrderId 1已付清(OrderValue 1000 = 100 + 500 + 400)。
我可以想到3种做法;使用游标,多次自行加入支付表,或者只是将数据加载到应用程序中,然后通过代码以旧式方式查看。任何人都可以想到如何避免这些解决方案,甚至为什么我应该采用我所想到的解决方案之一?
这最终会在SSRS报告中结束(使用SQL Server 2008)
答案 0 :(得分:2)
也许这会起作用
SELECT p.*
FROM Payment p JOIN Order o ON o.OrderId = p.OrderId
WHERE ( SELECT SUM(p2.PaymentAmount)
FROM Payment p2 ON p2.OrderId = o.OrderId
WHERE p2.PaymentDate <= p.PaymentDate
) >= o.OrderValue
AND p.PaymentDate = ( SELECT MIN(p3.PaymentDate)
FROM Payment p3 ON p.OrderId = o.OrderId
WHERE ( SELECT SUM(p4.PaymentAmount)
FROM Payment p4 ON p4.OrderId = o.OrderId
WHERE p4.PaymentDate <= p3.PaymentDate
) >= o.OrderValue
)
答案 1 :(得分:0)
如果你偏爱CTE以避免重复SUM逻辑,这对我有用:
WITH paidInFullPayments(PaymentId, OrderId, PaymentDate)
AS
(SELECT p.PaymentId, p.OrderId, p.PaymentDate
FROM payment p
INNER JOIN OrderTable o ON p.OrderId = o.OrderId
WHERE (SELECT sum(p2.PaymentAmt)
FROM payment p2
WHERE p2.PaymentDate <= p.PaymentDate
AND p2.OrderId = p.OrderId) >= o.OrderValue
)
SELECT *
FROM paidInFullPayments
INNER JOIN OrderTable o ON paidInFullPayments.OrderId = o.OrderId
WHERE paidInFullPayments.PaymentDate = (SELECT min(p3.PaymentDate)
FROM paidInFullPayments p3
WHERE p3.OrderId = o.OrderId)