[英]SQL query for calculating mtd, ytd values
I have a table with columns ID
, Title
, Date
, Amount
.我有一个包含
ID
、 Title
、 Date
、 Amount
列的表。
I need to get MTD, YTD amount values against each transaction based on Title
, Date
.我需要根据
Title
和Date
获取每笔交易的 MTD、YTD 金额值。
Is there anyone who had done this before?有没有人以前做过这个?
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]
The accepted solution is incorrect.接受的解决方案是不正确的。 Let's say we have a following 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
The accepted answer would give us these results:接受的答案会给我们这些结果:
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
This is due to the fact that each join multiplies the number of records by the number of matching records.这是因为每个连接都将记录数乘以匹配记录数。 This can be easily seen when the aggregation is removed:
当聚合被移除时,这可以很容易地看到:
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
Results:结果:
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
Here is a modified select that produces correct results:这是一个产生正确结果的修改后的选择:
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
Results:结果:
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
Here is a SQL Fiddle with all the current answers plus new solutions.这是一个包含所有当前答案以及新解决方案的SQL Fiddle 。
Another solution by using Cross Apply :使用Cross Apply的另一种解决方案:
see this sqlfiddle看到这个sqlfiddle
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
what if we have only one table how can we execute如果我们只有一张桌子怎么办?
for instance 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 by status,r_date例如 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
while running above query getting me an error could you please help me to get it Thanks在运行上面的查询时出现错误,你能帮我得到它吗谢谢
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.