如何使用SQL从日期字段按月分组


84

如何仅从日期字段中按月分组(而不是按天分组)?

我的日期字段如下所示:

2012-05-01

这是我当前的SQL:

select  Closing_Date, Category,  COUNT(Status)TotalCount from  MyTable
where Closing_Date >= '2012-02-01' and Closing_Date <= '2012-12-31'
and Defect_Status1 is not null
group by  Closing_Date, Category

Answers:


108

我会用这个:

SELECT  Closing_Date = DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0), 
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0), Category;

这将在每个月的第一天分组

`DATEADD(MONTH, DATEDIFF(MONTH, 0, '20130128'), 0)` 

会给'20130101'。我通常更喜欢这种方法,因为它将日期保留为日期。

或者,您可以使用如下所示的内容:

SELECT  Closing_Year = DATEPART(YEAR, Closing_Date),
        Closing_Month = DATEPART(MONTH, Closing_Date),
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY DATEPART(YEAR, Closing_Date), DATEPART(MONTH, Closing_Date), Category;

这实际上取决于您所需的输出是什么。(在您的示例中,不需要关闭年份,但是如果日期范围超出了年份范围,则可能会是)。


GarethD,谢谢男人,两种方法都工作正常。有没有一种方法可以将一个月中的年和月分组在一起?表示这样的格式:12月12日(12月是月份,12是年份)。谢谢
user1858332

第一种方法将执行此操作,您只需要格式化列即可。我建议在SQL之外进行此操作,但是如果必须这样做,则可以使用类似的方法SELECT STUFF(SUBSTRING(CONVERT(VARCHAR, CURRENT_TIMESTAMP, 6), 4, 6), 4, 1, '-');
GarethD 2013年

@GarethD您能解释一下如何使用0和日期之间的datediff吗?0不是日期。
irfandar

1
以及Closing_Date = DATEADD(MONTH,DATEDIFF(MONTH,0,Closing_Date),0)的作用是为什么不仅仅DATEADD(MONTH,DATEDIFF(MONTH,0,Closing_Date),0)
irfandar 2013年

3
@irfandar 0不是日期,但是SQL-Server隐式将其转换为1900年1月1日。第二个问题Closing_Date =只是列别名,它AS Closing_Date与表达式后的含义相同。它完全是主观的,但我个人认为该alias =术语比AS Alias。有关为什么我更喜欢它的更多信息,请阅读Aaron Bertrand的这篇文章
GarethD

41

使用DATEPART函数从日期中提取月份。

因此,您将执行以下操作:

SELECT DATEPART(month, Closing_Date) AS Closing_Month, COUNT(Status) AS TotalCount
FROM t
GROUP BY DATEPART(month, Closing_Date)

14
对于Mysql,您可以使用MONTH()或MONTHNAME()代替
DATEPART

如果您经常运行此查询,请考虑构建适当的索引。
user_0 2014年

加1即可简单回复。
berdem

9
这将考虑不同年份的月份相同-通常是无法预期的。
ivan_pozdeev

这会在1月
等号前加上

14

我使用FORMAT函数来完成此任务:

select
 FORMAT(Closing_Date, 'yyyy_MM') AS Closing_Month
 , count(*) cc 
FROM
 MyTable
WHERE
 Defect_Status1 IS NOT NULL
 AND Closing_Date >= '2011-12-01'
 AND Closing_Date < '2016-07-01' 
GROUP BY FORMAT(Closing_Date, 'yyyy_MM')
ORDER BY Closing_Month

9

通过增加MONTH(date_column)GROUP BY

SELECT Closing_Date, Category,  COUNT(Status)TotalCount
FROM   MyTable
WHERE  Closing_Date >= '2012-02-01' AND Closing_Date <= '2012-12-31'
AND    Defect_Status1 IS NOT NULL
GROUP BY MONTH(Closing_Date), Category

1

DATEPART函数在MySQL 5.6上不起作用,而是使用MONTH('2018-01-01')


1

试试这个:

select min(closing_date), date_part('month',closing_date) || '-' || date_part('year',closing_date) AS month,
Category, COUNT(Status)TotalCount 
FROM MyTable
where Closing_Date >= '2012-02-01' AND Closing_Date <= '2012-12-31'
AND Defect_Status1 is not null
GROUP BY month, Category,
ORDER BY 1

通过这种方式,您可以按合并的日期格式进行分组,并以-


0
SELECT  to_char(Closing_Date,'MM'), 
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY Category;

0

上面的SQL Server 2012版本,

SELECT  format(Closing_Date,'yyyy-MM') as ClosingMonth,
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY format(Closing_Date,'yyyy-MM'), Category;

-1

您可以通过使用Year(),Month()Day()和datepart()来实现。

在您的示例中,这将是:

select  Closing_Date, Category,  COUNT(Status)TotalCount from  MyTable
where Closing_Date >= '2012-02-01' and Closing_Date <= '2012-12-31' 
and Defect_Status1 is not null 
group by Year(Closing_Date), Month(Closing_Date), Category

这是无效的SQL
Mad Echet

好吧,这是有效的,但是由于您没有按选择的字段分组,因此带来了不可预测的结果。您可以在截止日期中使用任何值,只要日期和年份相同即可。
Mad Echet

-1

尝试以下代码

SELECT  Closing_Date = DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0), 
        Category,  
        COUNT(Status) TotalCount 
FROM    MyTable
WHERE   Closing_Date >= '2012-02-01' 
AND     Closing_Date <= '2012-12-31'
AND     Defect_Status1 IS NOT NULL
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0), Category;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.