【问题标题】:SQL grouping by month and yearSQL 按月和年分组
【发布时间】:2011-07-21 08:11:15
【问题描述】:

我不确定我应该在下面的 SQL 查询中写什么来显示像这样的“日期”列:“月-年”-“9-2011”。

SELECT MONTH(date) + '.' + YEAR(date) AS Mjesec, SUM(marketingExpense) AS SumaMarketing, SUM(revenue) AS SumaZarada 
FROM [Order]
WHERE (idCustomer = 1) AND (date BETWEEN '2001-11-3' AND '2011-11-3')
GROUP BY MONTH(date), YEAR(date)

所以,我想做的是将第一列的数据更改为显示月份和年份,而不是只显示月份。

【问题讨论】:

  • 这个问题有点让人困惑——你是要按日期排序吗?
  • 我不明白这一点:“我想显示第一列,因为我想对第一列进行不同的格式设置,使其独一无二”。
  • @JNK - Microsoft SQL @Chris - 不,我不想按日期排序,我只想将第一列的结果更改为显示月份和年份,而不是只显示月份。
  • 您不需要先按年分组,然后按月分组吗?你能展示一些示例输出吗?

标签: sql sql-server


【解决方案1】:

我猜这是 MS SQL,因为它看起来像 MS SQL 语法。

您应该在group by 中放入与select 中相同的内容。

例如:

Select MONTH(date)+'-'+YEAR(date), ....
...
...
...
group by MONTH(date)+'-'+YEAR(date)

【讨论】:

  • MONTH(date) 返回一个int。它需要一些cast -ing。
  • true .. 应该被转换为 varchar,尽管我的观点是你可以在选择中放入任何东西,只要相同的东西在组部分中。从sql的角度来看,理论上select语句是有效的。
  • no in MS SQL 这不会返回字符串,但我写的是为了分组的演示观点。
【解决方案2】:
Yet another alternative: 

Select FORMAT(date,'MM.yy')
...
...
group by FORMAT(date,'MM.yy')

【讨论】:

【解决方案3】:

对于 mariaDB,您可以:

SELECT DATE_FORMAT(date, '%m-%Y')
FROM [Order]
GROUP BY 
DATE_FORMAT(date, '%m-%Y')

链接:https://mariadb.com/kb/en/library/date_format/

【讨论】:

    【解决方案4】:

    您可以尝试乘法来调整年份和月份,使它们成为一个数字。根据我的测试,这比format(date,'yyyy.MM') 运行得快得多。我更喜欢在前一个月进行排序。从 MS SQL Server Express 12.0 版创建的代码。

    SELECT (YEAR(Date) * 100) + MONTH(Date) AS yyyyMM
    FROM [Order]
    ...
    GROUP BY (YEAR(Date) * 100) + MONTH(Date)
    ORDER BY yyyyMM
    

    【讨论】:

    • 我刚刚读到这篇文章,即将发表同样的评论。效率很高
    【解决方案5】:

    SQL Server 2012 以上,我更喜欢使用 format() 函数,更简单。

    SELECT format(date,'MM.yyyy') AS Mjesec, SUM(marketingExpense) AS SumaMarketing, SUM(revenue) AS SumaZarada 
    FROM [Order]
    WHERE (idCustomer = 1) AND (date BETWEEN '2001-11-3' AND '2011-11-3')
    GROUP BY format(date,'MM.yyyy')
    

    【讨论】:

    • 我不得不使用DATE_FORMAT(date, '%m.%Y')
    【解决方案6】:

    如果您想保留日期时间数据类型中的字段,请尝试使用:

    SELECT DATEADD(MONTH, DATEDIFF(MONTH, 0, o.[date]), 0) AS Mjesec, SUM(marketingExpense) AS SumaMarketing, SUM(revenue) AS SumaZarada 
    FROM [Order] o
    WHERE (idCustomer = 1) AND (o.[date] BETWEEN '2001-11-3' AND '2011-11-3')
    GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, o.[date]), 0)
    

    也可以轻松更改为按小时、天、周、年进行分组...
    我希望它对某人有用,

    问候!

    【讨论】:

    • 您的语句打开 3 个括号并关闭 1 个并且 datediff 需要 3 个参数。这行不通。
    【解决方案7】:
    SELECT CAST(MONTH(date) AS VARCHAR(2)) + '-' + CAST(YEAR(date) AS VARCHAR(4)) AS Mjesec, SUM(marketingExpense) AS SumaMarketing, SUM(revenue) AS SumaZarada 
    FROM [Order]
    WHERE (idCustomer = 1) AND (date BETWEEN '2001-11-3' AND '2011-11-3')
    GROUP BY CAST(MONTH(date) AS VARCHAR(2)) + '-' + CAST(YEAR(date) AS VARCHAR(4))
    

    或者正如@40-Love 提到的,您可以使用前导零进行投射:

    GROUP BY 
      CAST(YEAR(date) AS VARCHAR(4)) + '-' + right('00' + CAST(MONTH(date) AS VARCHAR(2)), 2) 
    

    【讨论】:

    • 这种方法按日期排序没用
    【解决方案8】:

    如果我理解正确的话。为了按要求对结果进行分组,您的 Group By 子句需要与您的 select 语句具有相同的表达式。

    GROUP BY MONTH(date) + '.' + YEAR(date)
    

    要将日期显示为“月-日期”格式,请更改“.”到 '-' 完整的语法是这样的。

    SELECT MONTH(date) + '-' + YEAR(date) AS Mjesec, SUM(marketingExpense) AS
    SumaMarketing, SUM(revenue) AS SumaZarada 
    FROM [Order]
    WHERE (idCustomer = 1) AND (date BETWEEN '2001-11-3' AND '2011-11-3')
    GROUP BY MONTH(date) + '.' + YEAR(date)
    

    【讨论】:

    • 猜你从未尝试过运行此代码,因为它不可能工作?
    【解决方案9】:

    在 postgresql 中,我可以使用日期格式函数 (to_char) 编写类似的查询,并仅按日期分组:

    SELECT to_char (datum, 'MM-YYYY') AS mjesec 
    FROM test 
    GROUP BY datum 
    ORDER BY datum;
    

    SQL-Server 肯定也可以做到这一点,不是吗?

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多