2016-10-03 3 views
1

У меня есть таблицы, как следующее:SQL запросов: граф, Группа по дате и году несколько столбцов

Date  | Type | 
2016/04/01 A 
2016/04/01 B 
2016/04/02 B 
2016/05/07 A 
    ...  ... 

Я пытаюсь сделать запрос, сосчитать каждого типа вхождение, сгруппированные по месяц/год:

DateByYearMonth | A | B | 
04/2016    1  2 
05/2016    1  0 
... 

Я пробовал много вещей, но у меня не могло быть того, что я хочу. Мой «базовый запрос»:

SELECT 
    COUNT(1) AS A 
FROM DBase.dbo.MyTable 
WHERE [Type] = 'A' 
AND Date BETWEEN '20140101' AND '20160930' 
GROUP BY YEAR(Date), 
     MONTH(Date) 

Может ли кто-нибудь мне помочь?

+0

Ваш тип столбец содержит только два ДАННЫЕ (A, B), фиксированные п DATAS (A, B, C , D) или неизвестное количество данных? –

+0

Вам нужно посмотреть ['PIVOT'] (https://msdn.microsoft.com/en-us/library/ms177410.aspx?f=255&MSPPError=-2147217396). – Richard

+0

@ RaphaëlAlthaus Он содержит фиксированные n данных – Elhendriks

ответ

3

Так что вы могли бы сделать что-то подобное, используя PIVOT на сгруппированных по Год/Месяц DATAS.

Конечно, вы должны добавить п желаемый ДАННЫЕ для столбцов, в PIVOT и главное выбрать

select 
    year, 
    month, 
    coalesce(A, 0) as A, 
    coalesce(B, 0) as B 
from 
    (select 
     [Type], 
     Year([Date]) as year, 
     Month([Date]) as month, count(*) c 
    from tt1 
    group by [Type], Year([Date]), Month([Date]) 
    ) t 

PIVOT(sum(c) 
     for [Type] in ([A], [B]) 
) as pvt 
2

Попробуйте это,

SELECT CONVERT (VARCHAR(7), [date], 20) AS DATEBYYEARMONTH, 
      Sum(CASE 
       WHEN type = 'A' THEN 1 
       ELSE 0 
       END)       A, 
      Sum(CASE 
       WHEN type = 'B' THEN 1 
       ELSE 0 
       END)       B 
    FROM #temp 
    GROUP BY CONVERT (VARCHAR(7), [date], 20) 
2

самый простой способ посчитать с case when условием:

SELECT CONCAT(MONTH(Date), '/', YEAR(Date)) AS YM , 
     COUNT(CASE WHEN type = 'A' THEN 1 END) AS [A] , 
     COUNT(CASE WHEN type = 'B' THEN 1 END) AS [B] 
FROM SomeTable 
GROUP BY MONTH(Date) , YEAR(Date) 

выход на основе вашей выборки данных:

enter image description here

1

Вы можете попробовать запрос, как этот

;WITH cte 
AS (SELECT 
    concat(RIGHT('00' + CONVERT(varchar(2), DATEPART(mm, date)), 2), '/', DATEPART(yyyy, date)) AS dt, 
    type, 
    COUNT(*) AS Cnt 
FROM dates1 
GROUP BY concat(RIGHT('00' + CONVERT(varchar(2), DATEPART(mm, date)), 2), '/', DATEPART(yyyy, date)), 
     type) 
SELECT 
    dt, 
    ISNULL([A], 0) AS [A], 
    ISNULL([B], 0) AS [B] 
FROM cte 
PIVOT (MAX(cnt) FOR type IN ([A], [B])) P 
1

я рекомендовал @ ответ RaphaëlAlthau в. Но, если вы хотите сделать его динамичным, попробуйте это.

DECLARE @TYPES VARCHAR(MAX), 
    @TYPESELECT VARCHAR(MAX)   
SELECT @TYPES = STUFF((SELECT ','+ QUOTENAME(TYP) FROM T1 GROUP BY TYP FOR XML PATH('')),1,1,'') ; 
SELECT @TYPESELECT = STUFF((SELECT ','+ 'ISNULL('+QUOTENAME(TYP)+',0) AS '+QUOTENAME(TYP) FROM T1 GROUP BY TYP FOR XML PATH('')),1,1,'') ; 

EXEC ('SELECT Mnth, '+ @TYPESELECT +' 
FROM 
(SELECT 
    [Typ], 
    CAST(YEAR([DateT]) AS VARCHAR) +''/''+CAST(MONTH([DateT]) AS VARCHAR) AS Mnth, 
    COUNT(DateT) C 
FROM T1 
GROUP BY [TyP], YEAR([DateT]), MONTH([DateT]) 
) t 
PIVOT(SUM(C) 
    FOR [Typ] IN ('+ @TYPES +') 
) AS PVT') 
1

Другой вариант PIVOT здесь:

SELECT * 
FROM (
    SELECT RIGHT(CONVERT(nvarchar(10),[Date],103),7) as DateByYearMonth, 
      [Type], 
      COUNT(*) as Tcount 
    FROM YourTable 
    GROUP BY RIGHT(CONVERT(nvarchar(10),[Date],103),7), [Type] 
) as t 
PIVOT (
    MAX(Tcount) FOR [Type] IN ([A],[B]) 
) as pvt 

Выход:

DateByYearMonth A B 
04/2016   1 2 
05/2016   1 NULL 
Смежные вопросы