简体   繁体   English

如何按月和年分组?

[英]How to group only by month and year?

I'm rather vaguely familiar with SQL. 我对SQL非常熟悉。 I use SQL Server 2012. 我使用SQL Server 2012。

I have this table: 我有这张桌子:

|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 column is of BIT data type. IsNormal列是BIT数据类型。

I need to group the table by SiteId and DateReview (only month and year). 我需要通过SiteIdDateReview (仅月份和年份)对表进行SiteId If in IsNormal column at least one row has property false, in grouped table it has to be False. 如果在IsNormal列中至少有一行具有属性false,则在分组表中它必须为False。

Here is the desired grouped table: 这是所需的分组表:

 | 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      |    

SQL Server can't aggregate bit columns as is, so cast it to int first, then use MIN and then cast it back to bit . SQL Server无法按原样聚合bit ,因此首先将其转换为int ,然后使用MIN然后将其转换回bit

To group by month I use the following formula: 要按月分组,我使用以下公式:

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

You can pick any anchor date instead of '20010101', it can be any first day of the month. 您可以选择任何锚定日期而不是“20010101”,它可以是该月的任何第一天。 The idea is simple. 这个想法很简单。 DATEDIFF(month,...) calculates the number of months between the anchor date and the value from the table. DATEDIFF(month,...)计算锚点日期与表格中的值之间的月数。 This is integer number - how many times the boundary of the month was crossed. 这是整数 - 跨越月份的边界的次数。 Then this number is added back to the anchor date. 然后将此数字添加回锚定日期。 Result of this expression is the value of DateReview truncated to the first day of the month. 此表达式的结果是截断到该月第一天的DateReview的值。

Query 询问

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')

Use year() and month() : 使用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;

This simply uses the year and month for the aggregation. 这只是使用年份和月份进行聚合。 It then pulls the column values using an aggregation function. 然后使用聚合函数拉取列值。 For DateReview , the appropriate function appears to be min() . 对于DateReview ,相应的函数似乎是min()

我已经使用过这段代码你也可以试试。

 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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM