【问题标题】:How I can select / sort dates by period intervals?如何按期间间隔选择/排序日期?
【发布时间】:2009-05-27 19:06:13
【问题描述】:

例如:

如果我们在表中有这样的记录:

25/06/2009
28/12/2009
19/02/2010
16/04/2011
20/05/2012

我想根据从当前日期开始的 6 个月间隔拆分/选择此日期。 结果应该是这样的: 从现在起0-6个月:第一次记录 7-12 个月后:第二次记录 ...

如果你把它简单化,我会非常感激,因为我把它变得非常愚蠢和复杂,比如:

declare variable like t1=curdate()+6 
t2=curdate()+12

...

然后选择记录以适应 curdate() 和 t1,然后是 t1 和 t2 等。

谢谢,

r.

【问题讨论】:

    标签: sql time intervals


    【解决方案1】:

    更正:倒退了,需要使用模数,而不是整数除法 - 抱歉...

    如果 MonthCount 是一个计算值,它计算自特定 12 月 31 日以来的月数,mod 是模除法(输出除法后的余数)

    Select [Column list here] 
    From Table
    Group By Case When MonthCount Mod 12 < 6 
             Then 0 Else 1 End  
    

    例如,在 SQL Server 中,您可以使用 DateDiff 函数

    Select [Column list here] 
    From Table
    Group By Case When DateDiff(month, myDateColumn, curdate) % 12 < 6 
             Then 0 Else 1 End
    

    (在 SQL Server 中,百分号是取模运算符)

    这会将所有记录分组到每个包含六个月数据的存储桶中

    【讨论】:

    • 我认为关键是他不想从特定的一月->六月和七月-十二月期间运行它,但 6 个月的期间是从当前日期即时计算的。所以从今天开始,上一个和下一个时期将是 2008-11-27 => 2009-05-27 AND 2009-05-27 => 2009-11-27
    【解决方案2】:
    SELECT (DATEDIFF(MONTH, thedate, GETDATE()) / 6) AS semester,
           SUM(receipt)
    FROM thetable
    GROUP BY semester
    ORDER BY semester
    

    关键的想法是按照给你“学期”的表达式进行分组和排序。

    【讨论】:

      【解决方案3】:

      这个问题真的让我很困惑,因为我实际上无法想出一个简单的解决方案。该死的。

      我能做到的最好的方法是对以下内容进行绝对的混蛋,您可以在其中创建一个临时表,将“期间”插入其中,重新连接到您的原始表,然后将其分组。

      假设您的内容表具有以下内容

      ID int
      Date DateTime
      Counter int
      

      而您正在尝试将六个月内的所有 counter 相加

      DECLARE @min_date datetime
      select @min_date = min(date) from test
      
      DECLARE @max_date datetime
      select @max_date = max(date) from test
      
      
      DECLARE @today_a datetime
      DECLARE @today_b datetime
      set @today_a = getdate()
      set @today_b = getdate()
      
      CREATE TABLE #temp (startdate DateTime, enddate DateTime)
      
      WHILE @today_a > @min_date
      BEGIN
          INSERT INTO #temp (startDate, endDate) VALUES (dateadd(month, -6, @today_a), @today_a)
          SET @today_a = dateadd(month, -6, @today_a)
      END
      WHILE @today_b < @max_date
      BEGIN
          INSERT INTO #temp (startDate, endDate) VALUES (@today_b, dateadd(month, 6, @today_b))
          SET @today_b = dateadd(month, 6, @today_b)
      END
      
      SELECT * FROM #temp
      
      SELECT 
          sum(counter), 
          'Between ' + Convert(nvarchar(10), startdate, 121) + ' => ' +  Convert(nvarchar(10), enddate, 121) as Period
      FROM test t
          JOIN #Temp ht
              ON t.Date between ht.startDate AND ht.EndDate
      GROUP BY 
          'Between ' + Convert(nvarchar(10), startdate, 121) + ' => ' +  Convert(nvarchar(10), enddate, 121)
      
      DROP TABLE #temp
      

      我真的希望有人能想出一个更好的解决方案,我的大脑显然已经融化了。

      【讨论】:

        【解决方案4】:

        不完全是你想要完成的,但你可以使用 DATEDIFF 函数来区分每条记录的范围:

        SELECT t.MonthGroup, SUM(t.Counter) AS TotalCount
        FROM (    
              SELECT Counter, (DATEDIFF(m, GETDATE(), Date) / 6) AS MonthGroup
              FROM Table
             ) t
        GROUP BY t.MonthGroup
        

        这将创建一个子查询,其中包含一个表达您想要的日期范围组的表达式。然后它将按此日期范围组对子查询进行分组,然后您可以对结果做任何您想做的事情。

        编辑:我根据您的示例修改了示例。

        【讨论】:

          【解决方案5】:

          如果您使用的是 SQL Server:

          SELECT *,
              (
                  FLOOR
                  (
                      (
                          DATEDIFF(month, GETDATE(), date_column)
                          - CASE WHEN DAY(GETDATE()) > DAY(date_column) THEN 1 ELSE 0 END
                      ) / 6.0
                  ) * 6
              ) AS SixMonthlyInterval
          FROM your_table
          

          如果您使用的是 MySQL:

          SELECT *,
              (
                  FLOOR
                  (
                      (
                          ((YEAR(date_column) - YEAR(CURDATE())) * 12)
                          + MONTH(date_column) - MONTH(CURDATE())
                          - CASE WHEN DAY(CURDATE()) > DAY(date_column) THEN 1 ELSE 0 END
                      ) / 6.0
                  ) * 6
              ) AS SixMonthlyInterval
          FROM your_table
          

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2012-06-19
            • 1970-01-01
            • 1970-01-01
            • 2016-03-23
            • 2019-05-13
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多