【问题标题】:SQL Server query to get total against each month of a year and return the year and month in date format not the string formatSQL Server 查询以获取一年中每个月的总数,并以日期格式而不是字符串格式返回年和月
【发布时间】:2019-11-19 10:44:05
【问题描述】:

我有一种情况,我必须计算一年中每个月的“总计”,并且我必须在保持日期的日期时间格式的同时显示一年中每个月的总计。我正在编写以下查询:

SELECT [DATE_FORMATION], sum(CO) CO, sum(Total_Members) Total_Members
from (
    select  convert(varchar(7),CAST([DATE_FORMATION] AS DATE),126) as [DATE_FORMATION],
    count([CO_ID]) as CO,
    sum(convert(int,[TOTAL_MEMBERS])) as Total_Members
    from COCores
    where cast([DATE_FORMATION] as date) >= Dateadd(Month, Datediff(Month, 0, DATEADD(m, -10, current_timestamp)), 0)
    group by [DATE_FORMATION]
) tmp
group by [DATE_FORMATION]

它给出了我需要的准确答案

但问题是它以“Varchar”格式生成日期,而我需要以日期时间格式生成日期,以便我可以进一步使用它。如何在保持日期时间格式的日期并获得相同结果的同时获得此结果。

【问题讨论】:

  • MySQL 是具有不同语法的不同产品。至于日期,它们没有格式,它们是二进制值。格式仅适用于将字符串解析为日期,将日期格式化为字符串。不要将日期存储为字符串。使用正确的类型,date。当你想生成字符串时,使用CONVERTFORMAT生成你想要的字符串
  • 数字也是如此。您不必将TOTAL_MEMBERS 转换为数字,它应该是一个以数字开头的数字
  • 您是否尝试过将日期转换为 Select Convert(DateTime,Date_Formation) as Date_Formation
  • @SyedWahhab OP 已经在这样做了。 这是开始的错误
  • @Sadia 你想要什么样的输出?您的代码明确截断了一天部分。你想展示什么?

标签: sql sql-server datetime


【解决方案1】:

日期没有格式,它们是二进制值,就像intdecimalbinaryDATE_FORMATION 应该是日期类型,例如datedatetimedatetime2。如果列使用正确的类型,则查询可以简化为:

select
    datefromparts(Year(DATE_FORMATION),MONTH(DATE_FORMATION),1) as DATE_FORMATION,  
    count([CO_ID]) as CO,
    sum([TOTAL_MEMBERS]) as Total_Members
from COCores
where 
    [DATE_FORMATION] as date) >= DATEFROMPARTS(Year(current_timestamp),1,1)
group by 
    YEAR(DATE_FORMATION),
    MONTH(DATE_FORMATION)

DATEFROMPARTS(Year(current_timestamp),1,1) 返回当前年份的第一个日期。这用于仅返回当前年份的行。结果使用 YEAR 和 MONTH 函数按 DATE_FORMATION 的年份和月份分组。最后,SELECT 通过使用DATEFROMPARTS 从组键生成日期值返回每个月的第一天

如果您使用a Calendar table,这样的查询会变得容易。日历表包含每个日期的行,例如 50 年和额外的年、月、日、周数、名称等列,可用于使报告更容易。日历表被大量索引,允许轻松查询,例如按年、季度、学期等。

假设DATE_FORMATIONdate,并且是一个包含日期、年份、月份和StartOfMonth 列的日历表,您可以将查询转换为:

select
    Calendar.StartOfMonth,  
    count([CO_ID]) as CO,
    sum([TOTAL_MEMBERS]) as Total_Members
from COCores inner join Calendar on DATE_FORMATION=Calendar.date
where 
    Calendar.Year= Year(current_timestamp)
group by 
    StartOfMonth

这个查询也很快,因为它可以利用YearDateStartOfMonth 上的任何索引

【讨论】:

    【解决方案2】:

    您可以像这样将所有日期转换为当月的第一天:

    DATEADD(DAY, 1, EOMONTH(DATE_FORMATION, -1))
    

    它产生一个DATE。您可以在 GROUP BY 和 SELECT 子句中使用此表达式:

    SELECT DATEADD(DAY, 1, EOMONTH(DATE_FORMATION, -1)), COUNT(CO_ID) AS CO, SUM(CONVERT(INT, TOTAL_MEMBERS)) AS Total_Members
    FROM COCores
    WHERE DATE_FORMATION >= -- calculate -10 months
    GROUP BY DATEADD(DAY, 1, EOMONTH(DATE_FORMATION, -1))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-07-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多