获取不同年份中按日/月的最早日期

Posted

技术标签:

【中文标题】获取不同年份中按日/月的最早日期【英文标题】: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 会发生什么,这是“最早的”? 所以这应该是最早的日期:) 我只想得到所有年份中最早的日期/月。 【参考方案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 函数不存在。

以上是关于获取不同年份中按日/月的最早日期的主要内容,如果未能解决你的问题,请参考以下文章

如何在sql中从给定的月份和年份获取月份的第一天和最后一天

iOS 核心数据总和数据按日期、月份年份

如何在Java中获取与01/01不同的日期开始的一年的上一个/当前季度和年份的开始和结束日期

如何快速获取一个月的对象

使用python从未知日期格式中获取年份

我们如何从当前日期取回 12 个月的日期 [重复]