簡體   English   中英

SQL 用於計算 mtd、ytd 值的查詢

[英]SQL query for calculating mtd, ytd values

我有一個包含IDTitleDateAmount列的表。

我需要根據TitleDate獲取每筆交易的 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的另一種解決方案:

看到這個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

如果我們只有一張桌子怎么辦?

例如 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.

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