[英]SQL query for calculating mtd, ytd values
我有一個包含ID
、 Title
、 Date
、 Amount
列的表。
我需要根據Title
和Date
獲取每筆交易的 MTD、YTD 金額值。
有沒有人以前做過這個?
Select t.title, t.Date,
Sum(y.Amount) YTD,
Sum(m.Amount) MTD
From table t
join table y
on y.Title = t.Title
and datediff(year, y.Date, t.Date) = 0
and y.Date <= t.Date
join table m
on m.Title = t.Title
and datediff(month, m.Date, t.Date) = 0
and m.Date <= t.Date
Group by t.title, t.Date
SELECT ID,
Title,
Date,
Amount,
MTD = SUM(Amount) OVER (PARTITION BY Title, DATEADD(MONTH, DATEDIFF(MONTH, 0, [Date]), 0)),
YTD = SUM(Amount) OVER (PARTITION BY Title, DATEADD(YEAR, DATEDIFF(YEAR, 0, [Date]), 0))
FROM [a_table]
接受的解決方案是不正確的。 假設我們有一個下表:
ID Title Date Amount
--- ------ ---------- ------
1 Cust A 2020-01-01 2.00
2 Cust A 2020-01-05 3.00
3 Cust A 2020-02-01 5.00
接受的答案會給我們這些結果:
Title Date YTD MTD
------ ---------- ----- -----
Cust A 2021-01-01 2.00 2.00
Cust A 2021-01-05 10.00 10.00
Cust A 2021-02-01 10.00 15.00
這是因為每個連接都將記錄數乘以匹配記錄數。 當聚合被移除時,這可以很容易地看到:
Select t.title, t.Date, y.Date, m.Date,
y.Amount,
m.Amount
From [table] t
join [table] y
on y.Title = t.Title
and datediff(year, y.Date, t.Date) = 0
and y.Date <= t.Date
join [table] m
on m.Title = t.Title
and datediff(month, m.Date, t.Date) = 0
and m.Date <= t.Date
Order by t.title, t.Date, y.Date, m.Date
結果:
Title t.Date y.Date m.Date y.Amount m.Amount
----- ---------- ---------- ---------- -------- --------
Cust A 2021-01-01 2021-01-01 2021-01-01 2 2
Cust A 2021-01-05 2021-01-01 2021-01-01 2 2
Cust A 2021-01-05 2021-01-01 2021-01-05 2 3
Cust A 2021-01-05 2021-01-05 2021-01-01 3 2
Cust A 2021-01-05 2021-01-05 2021-01-05 3 3
Cust A 2021-02-01 2021-01-01 2021-02-01 2 5
Cust A 2021-02-01 2021-01-05 2021-02-01 3 5
Cust A 2021-02-01 2021-02-01 2021-02-01 5 5
這是一個產生正確結果的修改后的選擇:
Select a.title, a.Date,
Sum(Case When datediff(year, b.Date, a.Date) = 0 Then b.Amount Else 0 End) YTD,
Sum(Case When datediff(month, b.Date, a.Date) = 0 Then b.Amount Else 0 End) MTD
From [table] a
join [table] b
on a.Title = b.Title
and b.Date <= a.Date
Group by a.title, a.Date
結果:
Title Date YTD MTD
------ ---------- ----- -----
Cust A 2021-01-01 2.00 2.00
Cust A 2021-01-05 5.00 5.00
Cust A 2021-02-01 10.00 5.00
這是一個包含所有當前答案以及新解決方案的SQL Fiddle 。
使用Cross Apply的另一種解決方案:
CREATE TABLE [table] (
ID int IDENTITY(1,1) PRIMARY KEY,
Title nvarchar(20),
Date date,
Amount money
)
INSERT INTO [table] (Title, Date, Amount)
VALUES ('Cust A', '2021-01-01', 2.00),
('Cust A', '2021-01-05', 3.00),
('Cust A', '2021-02-05', 4.00),
('Cust A', '2021-02-06', 5.00),
('Cust B', '2021-01-01', 20.00),
('Cust B', '2021-01-05', 30.00),
('Cust B', '2021-02-05', 40.00),
('Cust B', '2021-02-06', 50.00);
SELECT t1.title
,t1.Date
,t1.Amount
,t2.Amount_YTD
,t3.Amount_MTD
FROM [table] t1
CROSS APPLY
(
SELECT SUM(Amount) AS Amount_YTD
FROM [table] t2
WHERE t2.Date <= t1.Date
AND t1.Title = t2.Title
AND datediff(year, t1.Date, t2.Date) = 0
) t2
CROSS APPLY
(
SELECT SUM(Amount) AS Amount_MTD
FROM [table] t3
WHERE t3.Date <= t1.Date
AND t1.Title = t3.Title
AND datediff(month, t1.Date, t3.Date) = 0
) t3
如果我們只有一張桌子怎么辦?
例如 Select status, r_date, Sum(Case When datediff(year, r_date) = 0 Then hours Else 0 End) YTD, Sum(Case When datediff(month, r_date) = 0 Then hours Else 0 End) MTD From table 1 Group按狀態,r_date
在運行上面的查詢時出現錯誤,你能幫我得到它嗎謝謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.