【问题标题】:Obtaining the earliest date by day/month among different years获取不同年份中按日/月的最早日期
【发布时间】:2012-09-13 07:23:11
【问题描述】:

我有一个日期列表:

活动日期

- 06/04/1998
- 12/08/1980
- 29/11/2010
- 16/06/2002
- 20/10/2007
- 10/07/2000

我想按天/月获得这些年来最早的事件日期。所以最早的是 06/04/1998,如果我想获得最新的活动日期,它是 29/11/2010。我该如何写这个语法?

【问题讨论】:

  • 如果你有01/01/2012 会发生什么,这是“最早的”?
  • 所以这应该是最早的日期:) 我只想得到所有年份中最早的日期/月。

标签: sql oracle function date monthcalendar


【解决方案1】:
SELECT MAX(date), MIN(date), YEAR(date) year, MONTH(date) month
FROM table
GROUP BY YEAR(date), MONTH(date)

注意:这是伪代码 - 您需要在 oracle 中查找正确的函数来从日期中提取年份和月份。

您还将受益于函数索引:YEAR(date), MONTH(date), date

【讨论】:

    【解决方案2】:
    SELECT EXTRACT( MONTH FROM date_column),
           EXTRACT( DAY   FROM date_column),
           EXTRACT( YEAR  FROM date_column),
           date_column
      FROM table
     ORDER BY 1, 2, 3
    

    并选择第一条记录

    SELECT *
      FROM (SELECT EXTRACT( MONTH FROM date_column),
                   EXTRACT( DAY   FROM date_column),
                   EXTRACT( YEAR  FROM date_column),
                   date_column
              FROM table
             ORDER BY 1, 2, 3)
     WHERE rownum <= 1
    

    【讨论】:

      【解决方案3】:

      假设我了解您确实想要任何一年中按日/月计算的最早日期,那么analytic function 可以这样做:

      select dt from (
          select dt,
              dense_rank() over (partition by 1 order by to_char(dt, 'MMDD'),
                  to_char(dt, 'YYYY')) rn
          from t
      )
      where rn = 1;
      
      DT
      ----------
      06/04/1998
      

      这里的内部select 使用dense_rank() 根据我指定的顺序为每个日期分配排名-还有其他方法可以做到这一点,但将日/月转换为字符串似乎可行,并且如果您在一年多的时间里有同一天/同一个月,我将打破关系的年份包括在内(猜想在这种情况下您会想要最早的一年)。就其本身而言,加上一些额外的日期,看起来像这样:

      alter session set nls_date_format = 'DD/MM/YYYY';
      with t as (
          select to_date('06/04/1998') as dt from dual
          union all select to_date('12/08/1980') from dual
          union all select to_date('29/11/2010') from dual
          union all select to_date('16/06/2002') from dual
          union all select to_date('20/10/2007') from dual
          union all select to_date('10/07/2000') from dual
          union all select to_date('10/07/1999') from dual
          union all select to_date('06/04/1999') from dual
      )
      select dt,
          dense_rank() over (partition by 1 order by to_char(dt, 'MMDD'),
              to_char(dt, 'YYYY')) rn
      from t;
      
      DT         RN
      ---------- ----------
      06/04/1998      1
      06/04/1999      2
      16/06/2002      3
      10/07/1999      4
      10/07/2000      5
      12/08/1980      6
      20/10/2007      7
      29/11/2010      8
      
      8 rows selected.
      

      外部选择只选择等级为rn = 1dt 值。

      如果您想查找最新的,请将 order by 子句更改为包含 desc,以便它们以相反的顺序排序。

      【讨论】:

        【解决方案4】:

        如果该列表已经在表中。

        只需选择 Max(fieldName) 或 Min(fieldName)

        【讨论】:

        • 我使用了 MIN(fieldname) 但它给了我最早的年份而不是按日/月的最早日期..
        【解决方案5】:

        下面怎么样:

        从...中选择日期,其中 rownum = 1 order by month(date) * 100 + day(date) desc

        从...中选择日期,其中 rownum = 1 order by month(date) * 100 + day(date) asc

        【讨论】:

        • 为什么要添加?您可以在 order by 中放置多个列。
        • limit 不是有效的 Oracle 语法。
        • 我认为她想要的是按日/月排序而忽略年份。
        • @Ian Xu yupp 这就是我想要的
        • 您的查询还是不正确;您不能在与order by 相同的查询中使用rownum 谓词,而不使用子查询...加上monthyear 函数不存在。
        猜你喜欢
        • 1970-01-01
        • 2016-01-11
        • 2017-01-19
        • 2021-10-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-16
        • 2020-12-19
        相关资源
        最近更新 更多