【问题标题】:Return just the last day of each month with SQL使用 SQL 仅返回每个月的最后一天
【发布时间】:2011-08-17 11:41:23
【问题描述】:

我有一个表,其中包含数年来每个月的每一天的多条记录。有人可以帮我写一个只返回每个月的最后一天的查询。

【问题讨论】:

  • 多次重复 - 请搜索 SO
  • 请参阅您问题的相关部分。我相信你会在那里找到答案。
  • @Barry:这不是他要问的。
  • 所有这些结果都只是一个月.. 就像在 MAX(date) 中一样,我正在尝试这样做,但要经过多年.. 它稍微复杂一些......

标签: sql


【解决方案1】:

SQL Server(其他 DBMS 的工作方式相同或非常类似):

SELECT
  *
FROM
  YourTable
WHERE
  DateField IN (
    SELECT   MAX(DateField)
    FROM     YourTable
    GROUP BY MONTH(DateField), YEAR(DateField)
  )

DateField 上的索引在这里很有帮助。

PS:如果您的DateField 包含时间值,则以上内容将为您提供每个月的最后一条记录,而不是最后一天的记录值。在这种情况下,在进行比较之前使用一种方法将日期时间减少为其日期值,例如this one

【讨论】:

  • 对于 PostgreSQL 你需要使用:GROUP BY EXTRACT(MONTH FROM DateField), EXTRACT(YEAR FROM DateField).
  • 如果它可以帮助某人我只是将 mydatetime 转换为日期然后我做了一个比较 SELECT * FROM Table_ WHERE CONVERT(VARCHAR(10), yourDateTime, 111) IN ( SELECT MAX(CONVERT(VARCHAR(10), yourDateTime, 111)) AS LastDay FROM Table_ GROUP BY YEAR(yourDateTime), MONTH(yourDateTime))
【解决方案2】:

我能找到识别表中的日期字段是否为月末的最简单方法,就是简单地添加一天并检查 那个 天是否为 1。

where DAY(DATEADD(day, 1, AsOfDate)) = 1

如果您使用它作为您的条件(假设 AsOfDate 是您要查找的日期字段),那么它只会返回 AsOfDate 是该月最后一天的记录。

【讨论】:

  • 我发现这对我来说是最干净的解决方案;在表格中包含最后一个日期的行的最佳方法是什么?其中 (DAY(DATEADD(day, 1, AsOfDate)) = 1 或 AsOfDate = (select max(AsOfDate) from [Table]))?
  • 应该这样做,是的。这样,您将返回该月的最后一天或您有空的最后一天。唯一的问题是您最终可能会得到多个结果,不确定这是否是一个问题
  • 谢谢,好点重新多个结果;请注意,在我的最终解决方案中,我将最大日期时间设置为脚本顶部的一个变量,并在 where 性能测试中使用它。
  • 对我来说最干净的解决方案。
  • 如果数据库只包含工作日,这个@JavierRapoport 答案将给出错误结果。上面@Tomalak 选择的答案GROUP BY 更好,因为无论数据库中的数据如何,它总是会给出正确的结果。
【解决方案3】:

如果您可以使用 EOMONTH() 函数(例如 SQL Server),请使用它。它返回给定日期的一个月中的最后一个日期。

select distinct
Date 
from DateTable
Where Date = EOMONTH(Date)

或者,您可以使用一些日期数学。

select distinct
Date
from DateTable
where Date = DATEADD(MONTH, DATEDIFF(MONTH, -1, Date)-1, -1)

【讨论】:

    【解决方案4】:

    在 SQL Server 中,我通常是这样到达相对于任意时间点的一个月的最后一天:

    select dateadd(day,-day(dateadd(month,1,current_timestamp)) , dateadd(month,1,current_timestamp) )
    

    简而言之:

    1. 从您的参考时间点,
    2. 增加 1 个月,
    3. 然后,从结果值中减去它的日期(以天为单位)。

    瞧!您拥有包含参考时间点的月份的最后一天。

    获取每月的第一天更简单:

    select dateadd(day,-(day(current_timestamp)-1),current_timestamp)
    
    1. 从您的参考时间点,
    2. 减去(以天为单位),比当前的当月日期少 1。

    剥离/规范化无关的时间组件留给读者作为练习。

    【讨论】:

      【解决方案5】:

      获取一个月最后一天的简单方法是获取下个月的第一天并减去1。

      【讨论】:

      • 这仍然没有回答问题。
      • @FistOfFury 这是一个如何解决它的指针。由于没有符合标准的 SQL 数据库,因此在您告诉我您使用的数据库之前,我无法给您工作 SQL 代码。
      【解决方案6】:

      这应该适用于 Oracle DB

      select  distinct last_day(trunc(sysdate - rownum)) dt
          from dual
        connect by rownum < 430
         order by 1
      

      【讨论】:

        【解决方案7】:

        我做了以下事情,效果很好。我还想要 当前月份 的最大日期。这是我的输出。请注意 7 月的最后一个日期,即 24 日。我在 2017 年 7 月 24 日拉了它,因此结果

        Year    Month   KPI_Date
        2017    4       2017-04-28
        2017    5       2017-05-31
        2017    6       2017-06-30
        2017    7       2017-07-24
        
        
            SELECT  B.Year ,
            B.Month ,
            MAX(DateField) KPI_Date
        FROM    Table A
            INNER JOIN ( SELECT  DISTINCT
                                YEAR(EOMONTH(DateField)) year ,
                                MONTH(EOMONTH(DateField)) month
                         FROM   Table
                       ) B ON YEAR(A.DateField) = B.year
                              AND MONTH(A.DateField) = B.Month
        GROUP BY B.Year ,
            B.Month 
        

        【讨论】:

          【解决方案8】:
          SELECT * FROM YourTableName WHERE anyfilter 
          AND "DATE" IN (SELECT MAX(NameofDATE_Column) FROM YourTableName WHERE
          anyfilter GROUP BY
          TO_CHAR(NameofDATE_Column,'MONTH'),TO_CHAR(NameofDATE_Column,'YYYY'));
          

          注意:此答案确实适用于 Oracle DB

          【讨论】:

            【解决方案9】:

            这就是我刚刚解决这个问题的方法。 day_date 是日期字段,calendar 是保存日期的表。

            SELECT cast(datepart(year, day_date) AS VARCHAR) 
            + '-' 
            + cast(datepart(month, day_date) AS VARCHAR) 
            + '-' 
            + cast(max(DATEPART(day, day_date)) AS VARCHAR) 'DATE'
            FROM calendar
            GROUP BY datepart(year, day_date)
                ,datepart(month, day_date)
            ORDER BY 1
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2017-10-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2020-03-20
              相关资源
              最近更新 更多