タリーテーブル(別名ナンバーテーブル)を使用して、日付テーブルを作成する別の方法があります。私のコメントに注意してください。
-- Build the source data table.
declare @t table(Name nvarchar(10), InsertDate date, Size int);
insert into @t values
('john','20150630',1 )
,('john','20160110',10 )
,('john','20160112',100)
,('john','20160305',1000)
,('doe' ,'20160101',1 );
-- A year is fine, don't need a date data type
declare @year smallint = 2016;
WITH -- dummy rows for a tally table:
E AS (SELECT E FROM (VALUES (1),(1),(1),(1),(1),(1),(1),(1),(1),(1)) t(e)),
dateRange(totalDays, mn, mx) AS -- Get the range and number of months to create
(
SELECT DATEDIFF(MONTH, MIN(InsertDate), MAX(InsertDate)), MIN(InsertDate), MAX(InsertDate)
FROM @t
),
iTally(N) AS -- Tally Oh! Create an inline Tally (aka numbers) table starting with 0
(
SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 1))-1
FROM E a CROSS JOIN E b CROSS JOIN E c CROSS JOIN E d
),
RunningTotal AS -- perform a running total by year/month for each person (Name)
(
SELECT
yr = YEAR(DATEADD(MONTH, n, mn)),
mo = MONTH(DATEADD(MONTH, n, mn)),
Name,
Size = SUM(Size) OVER
(PARTITION BY Name ORDER BY YEAR(DATEADD(MONTH, n, mn)), MONTH(DATEADD(MONTH, n, mn)))
FROM iTally
CROSS JOIN dateRange
LEFT JOIN @t ON MONTH(InsertDate) = MONTH(DATEADD(MONTH, n, mn))
WHERE N <= totalDays
) -- Final output will only return rows where the year matches @year:
SELECT
name = ISNULL(name, LAG(Name, 1) OVER (ORDER BY yr, mo)),
yr, mo,
size = ISNULL(Size, LAG(Size, 1) OVER (ORDER BY yr, mo))
FROM RunningTotal
WHERE yr = @year
GROUP BY yr, mo, name, size;
結果:
name yr mo size
---------- ----------- ----------- -----------
doe 2016 1 1
john 2016 1 111
john 2016 2 111
john 2016 3 1111
あなたが外部結合のために使用することができますカレンダーテーブルを必要としています。 [this](https://www.mssqltips.com/sqlservertip/4054/creating-a-date-dimension-or-calendar-table-in-sql-server/)または[this](https:// sqlperformance)を参照してください。 .com/2013/01/t-sql-queries/generate-a-set-3)。 –
実際には、左側の外部結合テーブルとしていくつかの静的な値(数ヶ月間)を供給したいのですが、その方法を見つけることができませんでした.. – sotn
どのような静的な値ですか?また、顧客が過去2年間あなたに尋ねる場合、クエリを動的にして年を含める必要があることに注意してください。一度あなたがカレンダーテーブルを持っていればそれほど難しいことではありません。 'MIN(InsertDate)'と 'MAX(InsertDate)'を選択するサブクエリで年+月ごとにグループ分けし、開始日と終了日を取得するだけです。 –