我有两张桌子,
表-A
+---------+----+------------+------------+-----------+
| SurrKey | ID | StartDate | EndDate | Allotment |
+---------+----+------------+------------+-----------+
| 1 | 1 | 2015-01-01 | 2015-01-31 | 1000 |
| 2 | 1 | 2015-01-15 | 2015-02-15 | 1500 |
| 3 | 2 | 2015-01-01 | 2015-01-31 | 1200 |
| 4 | 2 | 2015-02-10 | 2015-03-10 | 1000 |
| 5 | 3 | 2015-01-01 | 2015-01-31 | 1000 |
| 6 | 3 | 2015-01-15 | 2015-02-14 | 1500 |
+---------+----+------------+------------+-----------+
表-B
+----+------------+------+
| ID | Date | Used |
+----+------------+------+
| 1 | 2015-01-01 | 800 |
| 1 | 2015-01-14 | 300 |
| 1 | 2015-01-15 | 100 |
| 1 | 2015-01-18 | 200 |
| 2 | 2015-01-01 | 700 |
| 2 | 2015-01-14 | 300 |
| 2 | 2015-01-15 | 150 |
| 2 | 2015-02-05 | 90 |
| 2 | 2015-02-11 | 100 |
| 3 | 2015-01-01 | 900 |
| 3 | 2015-01-15 | 150 |
+----+------------+------+
生成SQL查询以生成以下输出。
+------------+----+------------+------+---------------+--------------------+
| Row_number | ID | Date | Used | Running Total | RemainingAllotment |
+------------+----+------------+------+---------------+--------------------+
| 1 | 1 | 2015-01-01 | 800 | 800 | 200 |
| 2 | 1 | 2015-01-14 | 300 | 1100 | -100 |
| 3 | 1 | 2015-01-15 | 100 | 100 | 1400 |
| 4 | 1 | 2015-01-18 | 200 | 300 | 1200 |
| 5 | 2 | 2015-01-01 | 700 | 700 | 500 |
| 6 | 2 | 2015-01-14 | 300 | 1000 | 200 |
| 7 | 2 | 2015-01-15 | 150 | 1150 | 50 |
| 8 | 2 | 2015-02-05 | 90 | 90 | -90 |
| 9 | 2 | 2015-02-11 | 100 | 100 | 900 |
| 10 | 3 | 2015-01-01 | 900 | 900 | 100 |
| 11 | 3 | 2015-01-15 | 100 | 1000 | 0 |
| 12 | 3 | 2015-01-15 | 50 | 50 | 1450 |
+------------+----+------------+------+---------------+--------------------+
所需输出的一些细节:
附加要求。我为此编辑了样本表
答案 0 :(得分:1)
如果您可以使用窗口函数,那么您可以这样做:
DECLARE @A TABLE
(
SurrKey INT ,
ID INT ,
StartDate DATE ,
EndDate DATE ,
Allotment MONEY
)
DECLARE @B TABLE
(
ID INT ,
Date DATE ,
Used MONEY
)
INSERT INTO @A
VALUES ( 1, 1, '20150101', '20150131', 1000 ),
( 2, 1, '20150115', '20150215', 1500 ),
( 3, 2, '20150101', '20150131', 1200 ),
( 4, 2, '20150210', '20150310', 1000 )
INSERT INTO @B
VALUES ( 1, '20150101', 800 ),
( 1, '20150114', 300 ),
( 1, '20150115', 100 ),
( 1, '20150118', 200 ),
( 2, '20150101', 700 ),
( 2, '20150114', 300 ),
( 2, '20150115', 150 ),
( 2, '20150205', 90 ),
( 2, '20150211', 100 );
WITH cte
AS ( SELECT ROW_NUMBER() OVER ( ORDER BY ( SELECT 1 ) ) AS RN ,
b.ID ,
b.Date ,
b.Used ,
SUM(b.Used) OVER ( PARTITION BY b.ID, o.SurrKey ORDER BY b.Date ) AS RTotal ,
-SUM(b.Used) OVER ( PARTITION BY b.ID, o.SurrKey ORDER BY b.Date ) + o.Allotment AS Remaining
FROM @B b
OUTER APPLY ( SELECT TOP 1 *
FROM @A a
WHERE a.ID = b.ID
AND b.Date >= a.StartDate
ORDER BY a.StartDate DESC
) o
)
SELECT * FROM cte
输出:
RN ID Date Used RTotal Remaining
1 1 2015-01-01 800.00 800.00 200.00
2 1 2015-01-14 300.00 1100.00 -100.00
3 1 2015-01-15 100.00 100.00 1400.00
4 1 2015-01-18 200.00 300.00 1200.00
5 2 2015-01-01 700.00 700.00 500.00
6 2 2015-01-14 300.00 1000.00 200.00
7 2 2015-01-15 150.00 1150.00 50.00
8 2 2015-02-05 90.00 1240.00 -40.00
9 2 2015-02-11 100.00 100.00 900.00
修改强>
对于SQL 2008
,您可以使用:
WITH cte
AS ( SELECT ROW_NUMBER() OVER ( ORDER BY ( SELECT 1 ) ) AS RN ,
b.ID ,
b.Date ,
b.Used ,
o.SurrKey ,
o.Allotment
FROM @B b
OUTER APPLY ( SELECT TOP 1 *
FROM @A a
WHERE a.ID = b.ID
AND b.Date >= a.StartDate
ORDER BY a.StartDate DESC
) o
),
cte1
AS ( SELECT cte.RN ,
cte.ID ,
cte.Date ,
cte.Used ,
( SELECT SUM(Used)
FROM cte i
WHERE i.ID = cte.ID
AND i.SurrKey = cte.SurrKey
AND i.Date <= cte.Date
) AS RToTal ,
cte.Allotment
- ( SELECT SUM(Used)
FROM cte i
WHERE i.ID = cte.ID
AND i.SurrKey = cte.SurrKey
AND i.Date <= cte.Date
) AS Remaining
FROM cte
)
SELECT * FROM cte1