I have a list of dates:
Event dates
- 06/04/1998
- 12/08/1980
- 29/11/2010
- 16/06/2002
- 20/10/2007
- 10/07/2000
I wanna obtain the earliest event date by day/month among all these years. so the earliest is 06/04/1998 and if i wanna obtain the latest event date it is 29/11/2010. How do i write the syntax for this?
SELECT MAX(date), MIN(date), YEAR(date) year, MONTH(date) month
FROM table
GROUP BY YEAR(date), MONTH(date)
Note: This is pseudocode - you'll need to lookup what the correct function in oracle is to extract the year and month from a date.
You will also benefit from a function index on: YEAR(date), MONTH(date), date
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
and to select the first record
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
Assuming I understand that you really do want the earliest date by day/month in any year, then an analytic function can do this:
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
The inner select
here is using dense_rank()
to assign a ranking to each date, based on an ordering I specified - there are other ways to do this but converting the day/month to a string seems to work, and I included the year to break ties if you have the same day/month in more than one year (guessing you'd want the earliest year in that case). Just that on its own, with a few extra dates added, looks like this:
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.
The outer select just picks the dt
values with rank rn = 1
.
If you want to find the latest, change the order by
clauses to include desc
so they're sorted in reverse order.
how about following:
select date from ... where rownum = 1 order by month(date) * 100 + day(date) desc
select date from ... where rownum = 1 order by month(date) * 100 + day(date) asc
If that list already has in table.
Just SELECT Max(fieldName) or Min(fieldName)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.