你可以使用类似的东西:
SELECT fp.Name,
[Jan 2012] = SUM(CASE WHEN fp.Date >= '20120101' AND fp.Date < '20120201' THEN 1 ELSE 0 END),
[Feb 2012] = SUM(CASE WHEN fp.Date >= '20120201' AND fp.Date < '20120301' THEN 1 ELSE 0 END),
[Mar 2012] = SUM(CASE WHEN fp.Date >= '20120301' AND fp.Date < '20120401' THEN 1 ELSE 0 END),
[Apr 2012] = SUM(CASE WHEN fp.Date >= '20120401' AND fp.Date < '20120501' THEN 1 ELSE 0 END),
[May 2012] = SUM(CASE WHEN fp.Date >= '20120501' AND fp.Date < '20120601' THEN 1 ELSE 0 END),
[Jun 2012] = SUM(CASE WHEN fp.Date >= '20120601' AND fp.Date < '20120701' THEN 1 ELSE 0 END),
[Jul 2012] = SUM(CASE WHEN fp.Date >= '20120701' AND fp.Date < '20120801' THEN 1 ELSE 0 END),
[Aug 2012] = SUM(CASE WHEN fp.Date >= '20120801' AND fp.Date < '20120901' THEN 1 ELSE 0 END),
[Sep 2012] = SUM(CASE WHEN fp.Date >= '20120901' AND fp.Date < '20121001' THEN 1 ELSE 0 END),
[Oct 2012] = SUM(CASE WHEN fp.Date >= '20121001' AND fp.Date < '20121101' THEN 1 ELSE 0 END),
[Nov 2012] = SUM(CASE WHEN fp.Date >= '20121101' AND fp.Date < '20121201' THEN 1 ELSE 0 END),
[Dec 2012] = SUM(CASE WHEN fp.Date >= '20121201' AND fp.Date < '20130101' THEN 1 ELSE 0 END),
[Jan 2013] = SUM(CASE WHEN fp.Date >= '20130101' AND fp.Date < '20130201' THEN 1 ELSE 0 END),
[Feb 2013] = SUM(CASE WHEN fp.Date >= '20130201' AND fp.Date < '20130301' THEN 1 ELSE 0 END),
[Mar 2013] = SUM(CASE WHEN fp.Date >= '20130301' AND fp.Date < '20130401' THEN 1 ELSE 0 END),
[Apr 2013] = SUM(CASE WHEN fp.Date >= '20130401' AND fp.Date < '20130501' THEN 1 ELSE 0 END),
[May 2013] = SUM(CASE WHEN fp.Date >= '20130501' AND fp.Date < '20130601' THEN 1 ELSE 0 END),
[Jun 2013] = SUM(CASE WHEN fp.Date >= '20130601' AND fp.Date < '20130701' THEN 1 ELSE 0 END),
[Jul 2013] = SUM(CASE WHEN fp.Date >= '20130701' AND fp.Date < '20130801' THEN 1 ELSE 0 END),
[Aug 2013] = SUM(CASE WHEN fp.Date >= '20130801' AND fp.Date < '20130901' THEN 1 ELSE 0 END),
[Sep 2013] = SUM(CASE WHEN fp.Date >= '20130901' AND fp.Date < '20131001' THEN 1 ELSE 0 END),
[Oct 2013] = SUM(CASE WHEN fp.Date >= '20131001' AND fp.Date < '20131101' THEN 1 ELSE 0 END),
[Nov 2013] = SUM(CASE WHEN fp.Date >= '20131101' AND fp.Date < '20131201' THEN 1 ELSE 0 END),
[Dec 2013] = SUM(CASE WHEN fp.Date >= '20131201' AND fp.Date < '20140101' THEN 1 ELSE 0 END)
FROM f_page_views fp
WHERE fp.date > '2012-01-01 00:00:00.000'
AND fp.date < '2013-12-31 00:00:00.000'
GROUP BY fp.Name;
请注意,而不是使用WHEN MONTH(fp.Date) = 1 AND YEAR(fp.Date) = 2012
I have used WHEN fp.Date >= '20120101' AND fp.Date < '20120201'
,尽管这意味着后者会表现更好,特别是如果您有索引fp.Date
另一种方法是使用 PIVOT 函数:
WITH Data AS
( SELECT fp.Name,
ViewMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, fp.Date), 0),
Value = 1
FROM f_Page_Views
WHERE fp.date > '2012-01-01 00:00:00.000'
AND fp.date < '2013-12-31 00:00:00.000'
)
SELECT *
FROM Data
PIVOT
( SUM(Value)
FOR ViewMonth IN
( [20120101], [20120201], [20120301], [20120401], [20120501], [20120601],
[20120701], [20120801], [20120901], [20121001], [20121101], [20121201],
[20130101], [20130201], [20130301], [20130401], [20130501], [20130601],
[20130701], [20130801], [20130901], [20131001], [20131101], [20131201]
) pvt
如果您需要基于提供的日期范围动态创建的列,则可以将动态 SQL 与上述任一方法一起使用:
DECLARE @SQL NVARCHAR(MAX) = '';
DECLARE @StartDate DATETIME = '20120101',
@EndDate DATETIME = '20131231';
SELECT @SQL = @SQL + ',' + QUOTENAME(LEFT(DATENAME(MONTH, StartDate), 3) + ' ' + DATENAME(YEAR, StartDate)) + ' = SUM(CASE WHEN fp.Date >= ''' + CONVERT(VARCHAR, StartDate, 112) + ''' AND fp.Date < ''' + CONVERT(VARCHAR, EndDate, 112) + ''' THEN 1 ELSE 0 END)'
FROM ( SELECT [StartDate] = DATEADD(MONTH, Number, @StartDate),
[EndDate] = DATEADD(MONTH, 1 + Number, @StartDate)
FROM Master..spt_values
WHERE Number BETWEEN 0 AND DATEDIFF(MONTH, @StartDate, @Enddate)
AND Type = 'P'
) d
SET @SQL = 'SELECT fp.Name' + @SQL + ' FROM f_page_views fp WHERE fp.date > @Start AND fp.Date < @End GROUP BY fp.Name';
EXECUTE SP_EXECUTESQL @SQL, N'@Start DATETIME, @End DATETIME', @StartDate, @EndDate;
或者
DECLARE @SQL NVARCHAR(MAX) = '';
DECLARE @StartDate DATETIME = '20120101',
@EndDate DATETIME = '20131231';
SELECT @SQL = @SQL + ',' + QUOTENAME(CONVERT(VARCHAR, DATEADD(MONTH, Number, @StartDate), 112))
FROM Master..spt_values
WHERE Number BETWEEN 0 AND DATEDIFF(MONTH, @StartDate, @Enddate)
AND Type = 'P';
SET @SQL = 'WITH Data AS
( SELECT fp.Name,
ViewMonth = DATEADD(MONTH, DATEDIFF(MONTH, 0, fp.Date), 0),
Value = 1
FROM f_Page_Views fp
WHERE fp.date > @Start
AND fp.date < @End
)
SELECT *
FROM Data
PIVOT
( SUM(Value)
FOR ViewMonth IN (' + STUFF(@SQL, 1, 1, '') + ')
) pvt';
EXECUTE SP_EXECUTESQL @SQL, N'@Start DATETIME, @End DATETIME', @StartDate, @EndDate;