2016-10-03 99 views
1

我有一个表像下:SQL查询:计算,集团按日期和一年多列

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

我尽量让一个查询,统计按月分组每个类型occurence /年:

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

你的类型列仅包含两个DATAS(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它包含定氮条件DATAS – Elhendriks

回答

3

所以你可以做这样的事情,使用PIVOT对年/月DATAS分组。

当然,你必须添加n个期望DATAS为您列,在枢轴和主选择

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