如何使用sql从日期字段按月分组
Posted
技术标签:
【中文标题】如何使用sql从日期字段按月分组【英文标题】:How to group by month from Date field using sql 【发布时间】:2013-01-28 15:50:27 【问题描述】:如何从日期字段中仅按月分组(而不是按天分组)?
这是我的日期字段的样子:
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
【问题讨论】:
【参考方案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;
这将按每个月的第一天分组,所以
`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,谢谢伙计,这两种方法都很好用。有没有办法可以将年份和月份组合在一个字段中?意思是像这种格式显示:Dec-12(Dec 是月份,12 是年份)。谢谢 第一种方法会这样做,您只需要格式化列。我建议在 SQL 之外执行此操作,但如果必须这样做,您可以使用类似SELECT STUFF(SUBSTRING(CONVERT(VARCHAR, CURRENT_TIMESTAMP, 6), 4, 6), 4, 1, '-');
@GarethD 你能解释一下你是如何在 0 和日期之间使用 datediff 的吗? 0 不是日期。
还有什么 Closing_Date = DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0) 为什么不只是 DATEADD(MONTH, DATEDIFF(MONTH, 0, Closing_Date), 0) 跨度>
@irfandar 0 不是日期,但 SQL-Server 将其隐式转换为 1900 年 1 月 1 日。对于您的第二个问题,Closing_Date =
只是列别名,它与 AS Closing_Date
相同在表达式之后。这完全是主观的,但我个人发现alias =
符号比AS Alias
更容易阅读。有关我为什么更喜欢它的更多信息 read this article Aaron Bertrand。【参考方案2】:
使用DATEPART 函数从日期中提取月份。
所以你会做这样的事情:
SELECT DATEPART(month, Closing_Date) AS Closing_Month, COUNT(Status) AS TotalCount
FROM t
GROUP BY DATEPART(month, Closing_Date)
【讨论】:
mysql 可以使用 MONTH() 或 MONTHNAME() 代替 DATEPART 如果您经常运行此查询,请考虑构建适当的索引。 简单回复加1。 这会将不同年份的月份视为相同 - 这通常不是预期的。 这会为一月等添加一个“1”。它不会告诉你月份名称【参考方案3】:我使用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
【讨论】:
这不起作用,因为您不能在 ORDER BY 子句中使用别名【参考方案4】:通过在GROUP BY
中添加MONTH(date_column)
。
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
【讨论】:
【参考方案5】:试试这个:
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
这样你就可以通过连接的日期格式进行分组,并用 - 连接
【讨论】:
【参考方案6】:DATEPART 函数在 MySQL 5.6 上不起作用,而是使用 MONTH('2018-01-01')
【讨论】:
【参考方案7】: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;
【讨论】:
【参考方案8】: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;
【讨论】:
【参考方案9】:您可以使用 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 嗯,这是有效的,但会带来不可预知的结果,因为您没有按您选择的字段进行分组。只要日期和年份相同,您可以在截止日期中设置任何值。【参考方案10】:试试下面的代码
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;
【讨论】:
以上是关于如何使用sql从日期字段按月分组的主要内容,如果未能解决你的问题,请参考以下文章