由於inflagranti指出我的第一個解決方案遇到了Orders表所涵蓋年份出現漏洞的問題。我試圖動態創建所需年份的集合。
一個更直接的解決方案是使用一個numbers or tally table供應年。我的計數表叫做Number,並且有一個int類型的N列,數字爲0到1,000,000(含)。使用計數表可以提供多年加入的時間,以獲得跨越多年的訂單的多個行。對於ConsumedAmount,我正在計算OrderAmount *(訂單/訂單日期的一年中的幾天)。如果您想要某些不同的東西,如月份,周或財務上的任何東西,則需要修改。
注意我也使用SQL Server 2008點的功能,特別是date
數據類型,這在2008年是新從數相符表中獲取YearNumber,YearStartDate和YearEndDate的方法是不同的在2008年之前
請注意,由於閏年的額外一天,這些數字與您的示例略有差異。
; With Y as (select N as YearNumber
, dateadd(year, N-1, cast('0001-01-01' as date)) as YearStartDate
, dateadd(day, -1, dateadd(year, N, cast('0001-01-01' as date)))
as YearEndDate
from Number)
select O.OrderId
, Y.YearNumber
-- Next column is the OrderAmount * the ratio of
-- number of days in this year for this order
-- divided by the number of days of the order.
, OrderAmount * -- multiply the Order amount by the ratio of
((case when year(OrderDate) = year(Expirydate)
then datediff(day, OrderDate, ExpiryDate)
when YearNumber = year(OrderDate)
then datediff(day, OrderDate, YearEndDate)
when YearNumber = year(ExpiryDate)
then datediff(day, YearStartDate, ExpiryDate)
else datediff(day, YearStartDate, YearEndDate) end + 1)
/cast(datediff(day, OrderDate, ExpiryDate) + 1 as float))
from Orders O
inner join Y on Y.YearNumber between year(OrderDate) and year(ExpiryDate)
order by O.OrderId, YearNumber
測試數據:
create table Orders (OrderId int not null constraint Orders_PK primary key
, OrderAmount money
, OrderDate date
, ExpiryDate date)
go
insert into Orders
values (1, 100, '2008-01-01', '2009-12-31')
, (2, 200, '2009-01-01', '2010-12-31')
, (3, 300, '2010-01-01', '2011-12-31')
, (4, 3, '2010-01-01', '2010-06-30')
, (5, 400, '2007-01-01', '2009-05-31')
, (100, 1000, '2010-01-01', '2019-12-31')
查詢結果:
OrderId YearNumber
----------- ----------- ----------------------
1 2008 50.0683994528044
1 2009 49.9316005471956
2 2009 100
2 2010 100
3 2010 150
3 2011 150
4 2010 3
5 2007 165.532879818594
5 2008 165.986394557823
5 2009 68.4807256235828
100 2010 99.9452354874042
100 2011 99.9452354874042
100 2012 100.219058050383
100 2013 99.9452354874042
100 2014 99.9452354874042
100 2015 99.9452354874042
100 2016 100.219058050383
100 2017 99.9452354874042
100 2018 99.9452354874042
100 2019 99.9452354874042
爲什麼orderId 2的金額僅限於2009年且未拆分? –
編輯,謝謝! – dotnetlinc
每年總是會獲得相同的「CREDIT」,例如Order Date = 2010年7月1日和ExpiryDate = 2011年12月31日,訂單金額爲$ 150。每年有沒有75美元,等量?或者2010年獲得50美元,2011年獲得100美元,與每年的保有量成比例? –