SQL 服务器在日期范围内聚合
SQL Server aggregate over range of dates
我正在使用 SQL Server 2014。我需要在按客户和位置分区或分组的日期范围内汇总总计(总计)。关键是获取所有调整金额,并在适用于计费交易日期时将它们相加。
因此,所有在最后一个账单日期之后但小于下一个账单日期的调整都需要汇总并与账单金额一起很好地呈现。
参见示例:
+------------------+------------+------------+------------------+--------------------+
| TRANSACTION_TYPE | CUSTOMERID | LOCATIONID | TRANSACTION DATE | TRANSACTION AMOUNT |
+------------------+------------+------------+------------------+--------------------+
| bill | 215 | 102 | 7/7/2016 | 0.00 |
| bill | 215 | 102 | 6/6/2016 | 1.00 |
| adj | 215 | 102 | 6/1/2016 | .00 |
| adj | 215 | 102 | 5/8/2016 | [=11=].35 |
| adj | 215 | 102 | 5/7/2016 | .00 |
| bill | 215 | 102 | 5/6/2016 | 5.00 |
| bill | 215 | 102 | 4/7/2016 | 0.00 |
| adj | 215 | 102 | 4/2/2016 | .35 |
| adj | 215 | 102 | 4/1/2016 | $(0.50) |
| adj | 215 | 102 | 3/28/2016 | .00 |
| bill | 215 | 102 | 3/28/2016 | .00 |
| adj | 215 | 102 | 3/5/2016 | [=11=].33 |
| bill | 215 | 102 | 3/3/2016 | .00 |
+------------------+------------+------------+------------------+--------------------+
我想看的是:
+------------------+------------+------------+------------------+-------------+-------------------+
| TRANSACTION_TYPE | CUSTOMERID | LOCATIONID | TRANSACTION DATE | BILL AMOUNT | ADJUSTMENT AMOUNT |
+------------------+------------+------------+------------------+-------------+-------------------+
| bill | 215 | 102 | 7/7/2016 | 0.00 | $- |
| bill | 215 | 102 | 6/6/2016 | 1.00 | .35 |
| bill | 215 | 102 | 5/6/2016 | 5.00 | $- |
| bill | 215 | 102 | 4/7/2016 | 0.00 | .85 |
| bill | 215 | 102 | 3/28/2016 | .00 | [=12=].33 |
| bill | 215 | 102 | 3/3/2016 | .00 | $- |
+------------------+------------+------------+------------------+-------------+-------------------+
您需要:
- 首先将 table 设想为两个(虚拟)子 table,在 TransactionType 上;
- 然后使用 LEAD 函数获取要应用的调整的日期范围;和
- 最终执行 eft 连接。
以下未测试 SQL:
with
BillData as (
select
TransactionType,
CustomerID,
LocationID,
TransactionDate,
TransactionAmount,
lead(TransactionDate, 1) over (partition by CustomerID
order by TransactionDate) as NextDate
from @data bill
where TransactionType = 'bill'
),
AdjData as (
select
CustomerID,
TransactionDate,
sum(TransactionAmount) as AdjAmount
from @data adj
where TransactionType = 'adj'
)
select
bill.TransactionType,
bill.CustomerID,
bill.LocationID,
bill.TransactionDate,
sum(TransactionAmount) as BillAmount,
sum(AdjAmount) as AdjAmount
from BillData bill
left join AdjData adj
on adj.CustomerID = bill.CustomerID
and bill.TransactionDate <= adj.TransactionDate
and adj.TransactionDate < bill.NextDate
group by
bill.TransactionType,
bill.CustomerID,
bill.LocationID,
bill.TransactionDate
;
这就是我最后做的事情:
select
bill.TransactionType,
bill.CustomerID,
bill.LocationID,
bill.TransactionDate,
TransactionAmount as BillAmount,
sum(AdjAmount) as AdjAmount
from
(
select
TransactionType,
CustomerID,
LocationID,
TransactionDate,
TransactionAmount,
lag(TransactionDate, 1) over (partition by CustomerID, LocationID
order by TransactionDate) as PreviousDate --NextDate
from test1
where TransactionType = 'bill'
) as bill
left join
(
select
CustomerID,
LocationID,
TransactionDate,
TransactionAmount as AdjAmount
from test1
where TransactionType = 'adj'
) as adj
ON
adj.CustomerID = bill.CustomerID
and adj.LocationID = bill.LocationID
and adj.TransactionDate >= bill.PreviousDate
and adj.TransactionDate < bill.TransactionDate
group by
bill.TransactionType,
bill.CustomerID,
bill.LocationID,
bill.TransactionDate,
bill.TransactionAmount
order by 4 desc
我正在使用 SQL Server 2014。我需要在按客户和位置分区或分组的日期范围内汇总总计(总计)。关键是获取所有调整金额,并在适用于计费交易日期时将它们相加。
因此,所有在最后一个账单日期之后但小于下一个账单日期的调整都需要汇总并与账单金额一起很好地呈现。
参见示例:
+------------------+------------+------------+------------------+--------------------+
| TRANSACTION_TYPE | CUSTOMERID | LOCATIONID | TRANSACTION DATE | TRANSACTION AMOUNT |
+------------------+------------+------------+------------------+--------------------+
| bill | 215 | 102 | 7/7/2016 | 0.00 |
| bill | 215 | 102 | 6/6/2016 | 1.00 |
| adj | 215 | 102 | 6/1/2016 | .00 |
| adj | 215 | 102 | 5/8/2016 | [=11=].35 |
| adj | 215 | 102 | 5/7/2016 | .00 |
| bill | 215 | 102 | 5/6/2016 | 5.00 |
| bill | 215 | 102 | 4/7/2016 | 0.00 |
| adj | 215 | 102 | 4/2/2016 | .35 |
| adj | 215 | 102 | 4/1/2016 | $(0.50) |
| adj | 215 | 102 | 3/28/2016 | .00 |
| bill | 215 | 102 | 3/28/2016 | .00 |
| adj | 215 | 102 | 3/5/2016 | [=11=].33 |
| bill | 215 | 102 | 3/3/2016 | .00 |
+------------------+------------+------------+------------------+--------------------+
我想看的是:
+------------------+------------+------------+------------------+-------------+-------------------+
| TRANSACTION_TYPE | CUSTOMERID | LOCATIONID | TRANSACTION DATE | BILL AMOUNT | ADJUSTMENT AMOUNT |
+------------------+------------+------------+------------------+-------------+-------------------+
| bill | 215 | 102 | 7/7/2016 | 0.00 | $- |
| bill | 215 | 102 | 6/6/2016 | 1.00 | .35 |
| bill | 215 | 102 | 5/6/2016 | 5.00 | $- |
| bill | 215 | 102 | 4/7/2016 | 0.00 | .85 |
| bill | 215 | 102 | 3/28/2016 | .00 | [=12=].33 |
| bill | 215 | 102 | 3/3/2016 | .00 | $- |
+------------------+------------+------------+------------------+-------------+-------------------+
您需要:
- 首先将 table 设想为两个(虚拟)子 table,在 TransactionType 上;
- 然后使用 LEAD 函数获取要应用的调整的日期范围;和
- 最终执行 eft 连接。
以下未测试 SQL:
with
BillData as (
select
TransactionType,
CustomerID,
LocationID,
TransactionDate,
TransactionAmount,
lead(TransactionDate, 1) over (partition by CustomerID
order by TransactionDate) as NextDate
from @data bill
where TransactionType = 'bill'
),
AdjData as (
select
CustomerID,
TransactionDate,
sum(TransactionAmount) as AdjAmount
from @data adj
where TransactionType = 'adj'
)
select
bill.TransactionType,
bill.CustomerID,
bill.LocationID,
bill.TransactionDate,
sum(TransactionAmount) as BillAmount,
sum(AdjAmount) as AdjAmount
from BillData bill
left join AdjData adj
on adj.CustomerID = bill.CustomerID
and bill.TransactionDate <= adj.TransactionDate
and adj.TransactionDate < bill.NextDate
group by
bill.TransactionType,
bill.CustomerID,
bill.LocationID,
bill.TransactionDate
;
这就是我最后做的事情:
select
bill.TransactionType,
bill.CustomerID,
bill.LocationID,
bill.TransactionDate,
TransactionAmount as BillAmount,
sum(AdjAmount) as AdjAmount
from
(
select
TransactionType,
CustomerID,
LocationID,
TransactionDate,
TransactionAmount,
lag(TransactionDate, 1) over (partition by CustomerID, LocationID
order by TransactionDate) as PreviousDate --NextDate
from test1
where TransactionType = 'bill'
) as bill
left join
(
select
CustomerID,
LocationID,
TransactionDate,
TransactionAmount as AdjAmount
from test1
where TransactionType = 'adj'
) as adj
ON
adj.CustomerID = bill.CustomerID
and adj.LocationID = bill.LocationID
and adj.TransactionDate >= bill.PreviousDate
and adj.TransactionDate < bill.TransactionDate
group by
bill.TransactionType,
bill.CustomerID,
bill.LocationID,
bill.TransactionDate,
bill.TransactionAmount
order by 4 desc