如何按月和年分组?

时间:2016-10-20 08:55:25

标签: sql sql-server tsql sql-server-2012 group-by

我对SQL非常熟悉。我使用的是SQL Server 2012。

我有这张桌子:

|Id  | SiteId|    SiteDesc |IsNormal|     DateReview           |FrequencyId|
|3379|      5|     colon   |    1   |   2016-09-10 00:00:00.000|    1      |    
|3381|      5|     colon   |    0   |   2016-09-15 00:00:00.000|    1      |    
|3382|      5|     colon   |    1   |   2016-09-21 00:00:00.000|    1      |

|3489|      5|     colon   |    0   |   2016-08-10 00:00:00.000|    1      |    
|3851|      5|     colon   |    1   |   2016-08-16 00:00:00.000|    1      |

|3537|      2|     dogon   |    1  |    2016-05-05 00:00:00.000|    1      |    
|3863|      2|     dogon   |    1  |    2016-05-20 00:00:00.000|    1      |    

IsNormal列属于BIT数据类型。

我需要按SiteIdDateReview(仅限月份和年份)对表格进行分组。如果在IsNormal列中至少有一行具有属性false,则在分组表中它必须为False。

以下是所需的分组表:

 | SiteId|    SiteDesc |IsNormal|     DateReview           |FrequencyId|
 |      5|     colon   |    0   |   2016-09-10 00:00:00.000|    1      |        
 |      5|     colon   |    0   |   2016-08-10 00:00:00.000|    1      |    
 |      2|     dogon   |    1   |   2016-05-05 00:00:00.000|    1      |    

3 个答案:

答案 0 :(得分:6)

SQL Server无法按原样聚合bit列,因此请先将其转换为int,然后使用MIN,然后将其强制转换回bit

要按月分组,我使用以下公式:

DATEADD(month, DATEDIFF(month, '20010101', DateReview), '20010101')

您可以选择任何锚定日期而不是“20010101”,它可以是该月的任何第一天。这个想法很简单。 DATEDIFF(month,...)计算锚点日期与表格中的值之间的月数。这是整数 - 跨越月份的边界的次数。然后将此数字添加回锚定日期。此表达式的结果是截断到该月第一天的DateReview的值。

<强>查询

SELECT
    SiteId
    ,MIN(SiteDesc) AS SiteDesc
    ,CAST(MIN(CAST(IsNormal AS int)) AS bit) AS IsNormal
    ,MIN(DateReview) AS DateReview
    ,MIN(FrequencyId) AS FrequencyId
FROM T
GROUP BY
    SiteId
    ,DATEADD(month, DATEDIFF(month, '20010101', DateReview), '20010101')

答案 1 :(得分:3)

使用year()month()

select SiteId, min(SiteDesc) as SiteDesc,
       min(case when IsNormal = 0 then 0 else 1 end) as IsNormal,
       min(DateReview) as DateReview,
       min(FrequencyId) as FrequencyId
from t
group by SiteId, year(DateReview), month(DateReview)
order by min(DateReview) desc;

这只是使用年份和月份进行聚合。然后使用聚合函数拉取列值。对于DateReview,相应的函数似乎为min()

答案 2 :(得分:0)

我也使用过这段代码。

 select  CAST(MONTH(SalesDate) AS VARCHAR(2)) + '-' + CAST(YEAR(SalesDate) AS VARCHAR(4)),  sum(TSalesAmt) as 'GrandTotal' from CreditSales group by  CAST(MONTH(SalesDate) AS VARCHAR(2)) + '-' + CAST(YEAR(SalesDate) AS VARCHAR(4))