【问题标题】:How do I group DATE field by YEAR-MM in SQL Server?如何在 SQL Server 中按 YEAR-MM 对 DATE 字段进行分组?
【发布时间】:2012-06-26 19:06:47
【问题描述】:

我在查询中有一个日期字段,我确实希望得到这样的 GROUP BY 报告:

DATE    COUNT
2010-01  10
2010-02  2
...
2010-12  24
2012-13  34

在 SQL Server 上获取此文件的正确语法是什么?

【问题讨论】:

  • 不,那个线程是Mysql语法,这是SQL Server
  • @Mangist:SeanJohnson 链接到的答案将在 SQL Server 中工作——而且比这里的答案更清晰
  • 等一下,2012-13 是什么? 13 是一年中的一周吗?

标签: sql sql-server tsql group-by sql-date-functions


【解决方案1】:

所有这些到字符串的转换都有效,但我发现这种方法更有效,尽管可读性较差:

SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, [DATE]), 0), COUNT(*)
  FROM dbo.TheTable
  GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, [DATE]), 0); 

如果你不想重复表达,那么:

;WITH x AS (SELECT m = DATEADD(MONTH, DATEDIFF(MONTH, 0, [DATE]), 0)
  FROM dbo.TheTable)
SELECT m, COUNT(*)
  FROM x GROUP BY m;

这样输出仍然是日期/时间值,并且可以用于其他事情。而且不涉及任何乱七八糟的字符串转换。

【讨论】:

  • 我认为与使用多个日期函数相比,一次转换为字符串的工作量更少。真的更有效吗?
  • @RedFilter 这会产生与单个字符串转换完全相同的计划。好处是它保留为日期时间类型 - 因此您可以根据需要格式化输出,但您仍然可以将其用作日期时间类型。
  • @RedFilter 实际上我可以确切地说明为什么我总是使用日期时间操作。在幕后,这些是使用整数的非常简单的数学运算,已知比字符串更有效。与转换/分组完全相同的查询是唯一的区别是使用日期操作而不是字符串分组要快一秒以上:sqlfiddle.com/#!6/b155e/10
  • 感谢您提供性能信息。我在有意义时使用日期,在需要特定输出时使用字符串(即,我认为这个问题所要求的)。我认为这里没有必要制定严格的规则。
  • 数字/日期数学> 随时进行字符串操作。在最后可能的时刻转换为字符串。这是你应该遵守的规则。
【解决方案2】:
 CONVERT(VARCHAR(7), CreationDate, 120) as Date

【讨论】:

    【解决方案3】:

    你可以这样做:

    select convert(char(7), @myDate, 20)
    

    示例

    declare @myDate as DateTime
    set @myDate = '2012-06-23'
    select convert(char(7), @myDate, 20)
    

    输出

    -------
    2012-06
    

    所以完整的语句如下所示:

    select convert(char(7), myDate, 20), count(*) as Count
    from MyTable
    group by convert(char(7), myDate, 20)
    

    更新

    样本数据包含值2012-13。我假设这是一个错字,破折号后面的数字代表月份。

    【讨论】:

    • 已更新以涵盖令人困惑的示例数据。
    【解决方案4】:
    SELECT CAST(DATEPART(year, dateCol) as VARCHAR) + '-' + CAST(DATEPART(month, dateCol) as VARCHAR) as Date, count(*) As Count
    FROM myTable
    GROUP BY CAST(DATEPART(year, dateCol) as VARCHAR) + '-' + CAST(DATEPART(month, dateCol) as VARCHAR)
    

    【讨论】:

    • 事实上,要获得月份的前导零,您需要使用此语句而不是 SELECT CONVERT(VARCHAR(7), GETDATE(), 120)
    • Varchar 没有长度? Nooooooo....sqlblog.com/blogs/aaron_bertrand/archive/2009/10/09/…
    • @AaronBertrand 据记录,varchar 的默认长度为30,用于castconvert。我一直使用它,同时永远不会忘记在任何其他地方指定长度。
    • @GSerg 您可能知道这一点,但并非所有读者都知道。请阅读我的博文——重点不是你记住它在哪里是 30 和它在哪里是 1,而是你的代码始终如一,这样你就不必记住(并且读者不要拿代码和使用它在别处,然后想知道它为什么会坏)。
    • 年份使用 VARCHAR(4),月份使用 VARCHAR(2)。在这种情况下,它是微不足道的,所以我把它排除在表达式之外。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-02-04
    • 1970-01-01
    • 2010-09-07
    • 2015-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多