SQLのみを使用して毎月の集計を作成するのに助けが必要です。
次の表を想像してください。
TranID DateCode Account Value
1 20140101 1 5
2 20140106 1 -3
3 20140207 1 6
4 20140409 1 3
5 20140103 2 3
6 20140215 2 7
7 20140519 2 6
さまざまな日に取引がある2つのアカウントがあります。 7月にいると仮定して、この結果が得られるコードを記述したいと思います。
MonthID Account YTD
20140101 1 2
20140201 1 8
20140301 1 8
20140401 1 11
20140501 1 11
20140601 1 11
20140701 1 11
20140101 2 3
20140201 2 10
20140301 2 10
20140401 2 10
20140501 2 16
20140601 2 16
20140701 2 16
私は日付をMonthCodeに変換できるはずだと思っています
DATEADD(day, -DAY(DateCode) + 1, DateCode) AS MonthCode
テーブルをそれ自体に結合することでこれをどうにか解決できるはずだと思いますが、実際には数値が正しくありません。また、何とかしてトランザクションなしの月も取得する必要があります。
どんな助けも大歓迎です!
モックデータを生成するコード:
Create table #Tran(
TranID int identity(1,1),
DateCode Date,
AccountCode varchar(50),
Value int
);
insert into #Tran (DateCode, AccountCode, Value)
values ('20140101', '1', 5),
('20140106', '1', -3),
('20140201', '1', 6),
('20140401', '1', 3),
('20140101', '2', 3),
('20140201', '2', 7),
('20140501', '2', 6);
SQL Server 2012の場合、次のサンプルデータが与えられます。
CREATE TABLE #t(TranID INT, DateCode DATE, Account INT, Value INT);
CREATE CLUSTERED INDEX x ON #t(Account, DateCode);
INSERT #t VALUES(1,'20140101',1,5 ),(2,'20140106',1,-3),(3,'20140207',1,6 ),
(4,'20140409',1,3 ),(5,'20140103',2,3 ),(6,'20140215',2,7 ),(7,'20140519',2,6 );
私はこのクエリを使用します(最初の行をストアドプロシージャのパラメーターとして想像してください)。
DECLARE @year INT = 2014, @cutoff DATE = NULL; -- just state the year
-- and optionally an explicit cutoff date (leave NULL for today)
SET @cutoff = '20140731';
DECLARE @startdate DATE = DATEADD(YEAR, @year-1900, 0);
;WITH accounts(a) AS
(
SELECT DISTINCT Account FROM #t
WHERE DateCode >= @startdate
AND DateCode < DATEADD(YEAR, 1, @startdate)
),
months(m) AS
(
SELECT TOP (12) DATEADD(MONTH, ROW_NUMBER() OVER
(ORDER BY s.[object_id])-1, @startdate)
FROM sys.all_objects AS s
),
s AS
(
SELECT a.a, m.m, v = COALESCE(SUM(t.Value),0)
FROM accounts AS a
CROSS APPLY months AS m
LEFT OUTER JOIN #t AS t
ON t.DateCode >= m.m
AND t.DateCode < DATEADD(MONTH, 1, m.m)
AND t.Account = a.a
WHERE m.m < COALESCE(@cutoff, SYSDATETIME())
GROUP BY a.a, m.m
)
SELECT
MonthID = m,
Account = a,
YTD = SUM(v) OVER(PARTITION BY a ORDER BY m ROWS UNBOUNDED PRECEDING)
FROM s
ORDER BY a,m;
SQL Server 2012より古いバージョンを使用している場合は、ここで代替アプローチのいくつかを試してみるとよいでしょう。
最初に、MonthValue(20140101、20140201など)と呼ぶ、必要なすべての月を含むテーブルが必要になります。
クエリは次のようになります。
SELECT MonthValue.DateCode, #Tran.AccountID,
(SELECT Sum(Value) FROM #Tran as sub
WHERE sub.AccountID = #Tran.AccountID
AND sub.DateCode BETWEEN DATEADD(day, -DAY(MonthValue.DateCode) + 1, DateCode) AND MonthValue.DateCode) AS YTD
FROM MonthValue LEFT OUTER Join #Tran ON MonthValue.DateCode = #Tran.DateCode
GROUP BY MonthValue.DateCode, #Tran.AccountID
私はそれをテストしませんでした、しかしそれはあなたが少なくともあなたが必要とするものに近づくべきです。