There might be other better ways but does following work for you?
select client_id
,service_date
,other_stuff
from (
select client_id
,service_date
,other_stuff
,row_number() over (partition by client_id order by service_date) rn_min
,row_number() over (partition by client_id order by service_date desc) rn_max
from tbl
)
where (rn_min = 1 OR rn_max = 1) ;
Your belief that this should not be necessary is correct based on your assumptions. Normally this means the assumptions should be rechecked (unless there is data corruption or a bug). If you run the following you should get the same results from the first query as the second:
DROP TABLE t1;
CREATE TABLE t1 AS (
SELECT to_date('01-FEB-2011','DD-MON-YYYY')+level myDateColumn
FROM dual CONNECT BY level <=120);
select * from t1
where myDateColumn
between to_date('13-FEB-11', 'DD-MON-YY') AND TO_DATE('15-FEB-11', 'DD-MON-YY');
select myDateColumn from t1
where to_date(myDateColumn)
between to_date('13-FEB-11', 'DD-MON-YY') AND TO_DATE('15-FEB-11', 'DD-MON-YY');
To check some of the assumptions, can you show the results of the following query?
SELECT myDateColumn, to_date(myDateColumn)
, to_char(myDateColumn,'DD-MON-YY HH.MI.SS PM'), to_char(myDateColumn,'YYYY')
FROM myTable
WHERE to_date(myDateColumn)
BETWEEN to_date('13-FEB-11', 'DD-MON-YY') AND TO_DATE('15-FEB-11', 'DD-MON-YY');
The first three columns should all show identical information and the last should verify that the year is correct.
Best Answer
You can use EXTRACT (MONTH FROM DATE) function.
dbfiddle here