我需要从数据库中获取一组数据。该集合需要在日期范围内每月有一个条目,即使该值为空。总数是到年初的所有先前总数的总和。我设法制作了一个可以为所有客户使用一个月的产品,但我需要一年的时间。
我发现了这篇文章 - > Generate a resultset of incrementing dates in TSQL
并将其修改为:
DECLARE @range_start DATE = '1/1/2017'
DECLARE @range_end DATE = '12/31/2017'
SELECT DATEADD(day, number, @range_start
FROM
(SELECT DISTINCT number FROM master.dbo.spt_values
WHERE name IS NULL
) n
WHERE dateadd(MONTH, number, @range_start) < @range_end
现在我正试图将它包裹在我的查询中。
DECLARE @Year SMALLINT = 2017
DECLARE @Month TINYINT = 1
SELECT CLIENTCODE
,(
SELECT SUM(Tax_Credit)
FROM client_invoices ci
WHERE cm.CLIENTCODE = ci.CLIENTCODE
AND YEAR(InvDate) = @year
AND MONTH(InvDate) <= @month
AND Invoice_Revision =
(
SELECT MAX(Invoice_Revision)
FROM client_invoices ci2
WHERE ci2.CLIENTCODE = ci.CLIENTCODE
AND ci2.InvDate = ci.InvDate
AND ci2.InvNumber = ci.InvNumber)
) AS Year_2017_Tax_Credit_Totals
,(
SELECT SUM(Tax_Credit)
FROM client_invoices ci
WHERE cm.CLIENTCODE = ci.CLIENTCODE
AND YEAR(InvDate) = @year -1
AND MONTH(InvDate) <= @month
AND Invoice_Revision =
(
SELECT MAX(Invoice_Revision)
FROM client_invoices ci2
WHERE ci2.CLIENTCODE = ci.CLIENTCODE
AND ci2.InvDate = ci.InvDate
AND ci2.InvNumber = ci.InvNumber)
) AS Year_2016_Tax_Credit_Totals
FROM client_main cm
想法是替换;
DECLARE @Year smallint = 2017
DECLARE @Month tinyint = 1
在查询中使用月份列表中的值。我无法绕过如何做到这一点而不做一些疯狂的事情,如循环或指针或具有标量值函数的程序。
我该怎么做?
编辑:
以下是我正在尝试做的一个例子。
基础数据;
Clientname|Invoice Revision|Invoice Date|Invoice Amount
----------+----------------+------------+--------------
Client #1 | 0| 2/1/2017| 20
Client #1 | 0| 3/1/2017| 20
Client #1 | 1| 2/1/2017| 20
Client #1 | 1| 2/1/2017| 20
Client #1 | 1| 2/1/2017| 20
Client #2 | 0| 2/1/2017| 20
Client #2 | 0| 2/1/2017| 20
Client #1 | 0| 2/1/2016| 20
Client #1 | 0| 2/1/2016| 20
Client #1 | 0| 2/1/2016| 20
最终结果;
Clientname|Date |This_Years_Totals|Last_Years_Totals
----------+----------+-----------------+-----------------
Client #1 | Jan 2017| 0| 0
Client #1 | Feb 2017| 60| 60
Client #1 | Mar 2017| 80| 0
...
Client #2 | Jan 2017| 0| 0
Client #2 | Feb 2017| 40| 0
Client #2 | Mar 2017| 40| 0
...
答案 0 :(得分:1)
您希望每个客户端和每月有一行。所以首先交叉加入两个以获得所有组合。外面加入你的数字。
我为您感兴趣的发票(匹配最大修订版)使用一个WITH
子句,并使用递归查询生成月份。
with last_revision_invoices as
(
select top(1) with ties
clientcode,
year(invdate) as year,
month(invdate) as month,
tax_credit
from client_invoices ci
order by case when invoice_revision = max(invoice_revision) over (partition by clientcode, invdate, invnumber) then 1 else 2 end
)
, months as (
select year(@range_start) as year, month(@range_start) as month
union all
select case when month < 12 then year else year + 1 end, (month % 12) + 1
from months
where year < year(@range_end) or (year = year(@range_end) and month < month(@range_end))
)
select c.clientcode, m.year, m.month, coalesce(cur.total, 0) as total_then, coalesce(prev.total, 0) as total_previous_year
from client_main c
cross join months m
left join
(
select clientcode, year, month, sum(tax_credit) as total
from last_revision_invoices
group by clientcode, year, month
) cur on cur.clientcode = c.clientcode and cur.year = m.year and cur.month = m.month
left join
(
select clientcode, year, month, sum(tax_credit) as total
from last_revision_invoices
group by clientcode, year, month
) prev on prev.clientcode = c.clientcode and prev.year = m.year - 1 and prev.month = m.month
order by c.clientcode, m.year, m.month;
Rextester演示:http://rextester.com/NUOM2966