簡體   English   中英

T-SQL在查詢周圍包裹一個增量日期

[英]T-SQL Wrapping an increment date around a query

我需要從數據庫中獲取一組數據。 即使該集合為空,該集合在日期范圍內每月也必須有一個條目。 總計是到年初的所有先前總計的總和。 我設法制作了一個可以供所有客戶使用一個月的產品,但是我需要一年的時間。

我發現這篇文章-> 在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
...

您希望每個客戶和每個月一行。 因此,首先將兩者交叉加入以獲得所有組合。 然后外加入你的數字。

我對感興趣的發票使用一個WITH子句(與最大修訂版本匹配),對一個遞歸查詢使用一個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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM