Jason 完全正确,但我会为您节省一些时间和 link 我过去成功使用的日历表脚本,用于快速表。
为了死链接,这里是您正在查看的宿舍的相关部分,尽管我建议阅读我链接的页面,因为它是一个很好的教程。
DECLARE @StartDate DATE = '20000101', @NumberOfYears INT = 30;
-- prevent set or regional settings from interfering with
-- interpretation of dates / literals
SET DATEFIRST 7;
SET DATEFORMAT mdy;
SET LANGUAGE US_ENGLISH;
DECLARE @CutoffDate DATE = DATEADD(YEAR, @NumberOfYears, @StartDate);
-- this is just a holding table for intermediate calculations:
CREATE TABLE #dim
(
[date] DATE PRIMARY KEY,
[day] AS DATEPART(DAY, [date]),
[month] AS DATEPART(MONTH, [date]),
FirstOfMonth AS CONVERT(DATE, DATEADD(MONTH, DATEDIFF(MONTH, 0, [date]), 0)),
[MonthName] AS DATENAME(MONTH, [date]),
[week] AS DATEPART(WEEK, [date]),
[ISOweek] AS DATEPART(ISO_WEEK, [date]),
[DayOfWeek] AS DATEPART(WEEKDAY, [date]),
[quarter] AS DATEPART(QUARTER, [date]),
[year] AS DATEPART(YEAR, [date]),
FirstOfYear AS CONVERT(DATE, DATEADD(YEAR, DATEDIFF(YEAR, 0, [date]), 0)),
Style112 AS CONVERT(CHAR(8), [date], 112),
Style101 AS CONVERT(CHAR(10), [date], 101)
);
-- use the catalog views to generate as many rows as we need
INSERT #dim([date])
SELECT d
FROM
(
SELECT d = DATEADD(DAY, rn - 1, @StartDate)
FROM
(
SELECT TOP (DATEDIFF(DAY, @StartDate, @CutoffDate))
rn = ROW_NUMBER() OVER (ORDER BY s1.[object_id])
FROM sys.all_objects AS s1
CROSS JOIN sys.all_objects AS s2
-- on my system this would support > 5 million days
ORDER BY s1.[object_id]
) AS x
) AS y;
请注意,这是上面的临时表,您可能希望将其具体化为架构中某处的真实表。
一旦您有了这个生成的表,您就可以通过从日历表中选择一组不同的季度开始您的上一个查询,然后将左外部连接到您的常规查询。这就是你如何获得那些“缺失”的日期。最后,请注意我使用了 coalesce 来为您的 USD 度量显示一个零数字,而不是使用空值:
SELECT distinct
'Q' + CAST(quarter as varchar(1)) as Quarter,
COALESCE(total, 0) as USD
FROM #dim as d
LEFT OUTER JOIN YourTable yt
ON d.quarter = yt.quarter