2013-03-11 2 views
1

У меня есть следующий запрос, который отлично работает, когда я просто искал данные в 2012 году. Сейчас мы в 2013 году, и это становится немного запутанным. Я пытался сделать запрос, где он возвращает результаты с форматом даты, который будет выглядеть следующим образом: январь 2012 года, февраль 2012 года .... а затем также январь 2013 года, февраль 2013 года. Как я могу это достичь? БлагодаряОшибка форматирования даты SQL

SELECT 
    fp.name             AS [Name], 
    YEAR(fp.date)           AS [Year], 
    SUM(CASE WHEN MONTH(fp.date) = '1' THEN 1 ELSE 0 END) AS [JAN],  
    SUM(CASE WHEN MONTH(fp.date) = '2' THEN 1 ELSE 0 END) AS [FEB], 
    SUM(CASE WHEN MONTH(fp.date) = '3' THEN 1 ELSE 0 END) AS [MAR], 
    SUM(CASE WHEN MONTH(fp.date) = '4' THEN 1 ELSE 0 END) AS [APR], 
    SUM(CASE WHEN MONTH(fp.date) = '5' THEN 1 ELSE 0 END) AS [MAY], 
    SUM(CASE WHEN MONTH(fp.date) = '6' THEN 1 ELSE 0 END) AS [JUN], 
    SUM(CASE WHEN MONTH(fp.date) = '7' THEN 1 ELSE 0 END) AS [JUL], 
    SUM(CASE WHEN MONTH(fp.date) = '8' THEN 1 ELSE 0 END) AS [AUG], 
    SUM(CASE WHEN MONTH(fp.date) = '9' THEN 1 ELSE 0 END) AS [SEP], 
    SUM(CASE WHEN MONTH(fp.date) = '10' THEN 1 ELSE 0 END) AS [OCT], 
    SUM(CASE WHEN MONTH(fp.date) = '11' THEN 1 ELSE 0 END) AS [NOV], 
    SUM(CASE WHEN MONTH(fp.date) = '12' THEN 1 ELSE 0 END) AS [DEC], 
    COUNT(*)             AS [Overall] 

    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 
    year(fp.date) 
+0

Вы пытаетесь добавить поля запрос каждый год, как '[Jan 2012] ,,, [Январь 2013], ... [Dec 2013]'? Итак, если вы фильтруете «2012-01-01» и «2015-12-31», у вас должно быть 48 полей? – Kaf

+0

Да, это то, что я пытался: | – Bushell

+1

Не знаете, как ваш передний конец (если есть) справится с ним, когда у вас есть другое количество полей в результирующем наборе для разных значений даты. Чтобы получить такие результаты, вам может потребоваться использовать «PIVOT», [здесь аналогичный вопрос] (http://stackoverflow.com/questions/7145694/pivot-with-month). – Kaf

ответ

1

Вы могли бы использовать что-то вроде:

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 я использовал 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; 
+0

Отлично! Большое спасибо, это именно то, что я искал. – Bushell

+0

Обратите внимание: я предположил, что SQL-Server был СУБД на основе использования квадратных скобок в вопросе. – GarethD

Смежные вопросы