TSQL 运行 总计开始和结束日期
TSQL Running total with start and end date
我有两个table,
Table_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 |
+---------+----+------------+------------+-----------+
Table_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 |
+------------+----+------------+------+---------------+--------------------+
所需输出的一些详细信息:
- 在Row_number2,是负100,因为他用光了所有hist
分配
- 在 Row_number 3,从这个日期开始,他有新的分配,
运行 应重置此 ID 的总数
- 在Row_number8,它的负90,重置这个ID的总计运行,
由于 Surrkey 3 已过期,开始日期只会在 2015-02-10
- 在 Row_number 9 上,Surrkey 4 在 table A
上的新用法
附加要求。我为此
编辑了示例 table
- 在 Row_Number 11 和 12,有相同的日期和相同的 ID,因为您必须用完所有剩余的配额才能使用下一个配额,在本例中为 Surrkey 6。
如果你可以使用窗口函数,那么你可以这样做:
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
我有两个table,
Table_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 |
+---------+----+------------+------------+-----------+
Table_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 |
+------------+----+------------+------+---------------+--------------------+
所需输出的一些详细信息:
- 在Row_number2,是负100,因为他用光了所有hist 分配
- 在 Row_number 3,从这个日期开始,他有新的分配, 运行 应重置此 ID 的总数
- 在Row_number8,它的负90,重置这个ID的总计运行, 由于 Surrkey 3 已过期,开始日期只会在 2015-02-10
- 在 Row_number 9 上,Surrkey 4 在 table A 上的新用法
附加要求。我为此
编辑了示例 table- 在 Row_Number 11 和 12,有相同的日期和相同的 ID,因为您必须用完所有剩余的配额才能使用下一个配额,在本例中为 Surrkey 6。
如果你可以使用窗口函数,那么你可以这样做:
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