good
A reader, February 04, 2003 - 1:58 am UTC
dint know sql cud be used like this
Changed query to run by sysdate
Saru, February 04, 2003 - 9:22 am UTC
Thanks Tom,
I changes the query, to use sysdate, and to select only on current year.
select trunc(add_months(dt,-2),'mm') start_date
,dt end_date
,to_char( dt, 'yyyy - q' ) qtr
from (select add_months( trunc(sysdate,'Y') -1 , rownum*3) dt
from all_objects
where rownum <= 4)
where sysdate between trunc(add_months(dt,-2),'mm') and dt;
I still think there is a better way to do it by using dual.
Excellent trick to take the last day of the year as the base date.
Thanks
Saru, February 04, 2003 - 9:36 am UTC
I got it... :)
select trunc(add_months(add_months(trunc(sysdate,'Y') -1 ,to_number(to_char(sysdate,'Q')) * 3),-2),'MM') start_date
,add_months(trunc(sysdate,'Y') -1 ,to_number(to_char(sysdate,'Q')) * 3) end_date
,to_char(sysdate,'YYYY - q') qtr from dual
/
Slightly simpler version
Andrew, February 04, 2003 - 10:15 am UTC
Before reading this I didn't know trunc() did different levels of truncation - incredibly useful information just when I needed it!
This version avoids all the to_char/to_number conversions (apart from the qtr string):
SELECT trunc(SYSDATE) AS "SYSDATE",
trunc(SYSDATE, 'q') AS "Q_START",
add_months(trunc(SYSDATE, 'q'), 3) - 1 AS "Q_END",
to_char(SYSDATE, 'yyyy - q' ) AS "QTR"
FROM dual
Date Scaling
Fred, September 02, 2003 - 3:15 pm UTC
I have a similar situation. Let's say I have a simple table like this:
SEQUENCE_NUMBER EFFECTIVE_DATE
6 20021223
6 20021020
6 20021017
6 20021011
...
...
And I want the output of a query to be like:
Start_Date End_Date
12/23/02 00/00/00
10/20/02 12/22/02
10/17/02 10/19/02
10/11/02 10/16/02
...
...
Where the End_Date column of the very first row will always be 00/00/00 and the subsequent ones are 1 day subtracted from the Start_Date column of the previous row.
Now I am able to do the scaling (subtract 1 day) part, but I haven't figured out how to make the first row always 00/00/00.
Could you offer some insight?
September 02, 2003 - 9:11 pm UTC
ops$tkyte@ORA920> select to_char( to_date( edate,'yyyymmdd'), 'mm/dd/yy' ),
2 nvl( to_char( to_date( lag(edate-1) over (order by edate desc),'yyyymmdd'), 'mm/dd/yy'), '00/00/00' )
3 from t
4 order by edate desc ;
TO_CHAR( NVL(TO_C
-------- --------
12/23/02 00/00/00
10/20/02 12/22/02
10/17/02 10/19/02
10/11/02 10/16/02
Never mind
fred, September 02, 2003 - 7:23 pm UTC
I got help.
SQL> select * from t_edate;
SEQUENCE_NUMBER EFFECTIVE
--------------- ---------
6 23-DEC-02
6 20-OCT-02
6 17-OCT-02
6 11-OCT-02
8 10-DEC-02
8 30-DEC-02
6 rows selected.
1 select
2 b.sequence_number, to_char(b.effective_date,'MM/DD/YY'), nvl(to_char(a.effective_date-1,'MM/DD/YY'),'00/00/00')
3 from
4 (select sequence_number,effective_date, rownum rnum from
5 (select * from t_edate order by sequence_number, effective_date desc)) a,
6 (select sequence_number,effective_date,rownum-1 rnum from
7 (select * from t_edate order by sequence_number, effective_date desc)) b
8 where
9 b.rnum=a.rnum (+) and
10 b.sequence_number=a.sequence_number (+)
11* order by 1 desc, 2 desc
SQL> /
SEQUENCE_NUMBER TO_CHAR( NVL(TO_C
--------------- -------- --------
8 12/30/02 00/00/00
8 12/10/02 12/29/02
6 12/23/02 00/00/00
6 10/20/02 12/22/02
6 10/17/02 10/19/02
6 10/11/02 10/16/02
6 rows selected.
September 02, 2003 - 9:19 pm UTC
see above -- much easier with analytics!!!
So Simple, Yet Effective
fred, September 03, 2003 - 9:58 am UTC
Now I will sit in the corner with the good ol' dunce cap on my head. I must overcome... ughhh.
Thanks.
Fred
Generate one month date with or without date
Sean, January 09, 2004 - 4:44 pm UTC
Hi Tom,
create table t1(c1 date, c2 varchar2(20));
insert into t1
values(sysdate-5, 'A');
insert into t1
values(sysdate, 'B');
I would like to use a query to generate whole month with or without data.
someting like:
01-JAN-04
02-JAN-04
03-JAN-04
04-JAN-04 A
05-JAN-04
06-JAN-04
07-JAN-04
08-JAN-04
09-JAN-04 B
.
.
.
31-JAN-04
Thanks so much for your help.
Sean
January 10, 2004 - 10:23 am UTC
ops$tkyte@ORA9IR2> /*
DOC>drop table t;
DOC>
DOC>create table t ( c1 date, c2 varchar2(1) );
DOC>
DOC>insert into t values ( sysdate-5, 'a' );
DOC>insert into t values ( sysdate, 'b' );
DOC>*/
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select x.dt, t.c2
2 from (
3 select first+rownum-1 dt
4 from ( select trunc(last_day(max(c1))) last, trunc(min(c1),'mm') first from t ),
5 all_objects
6 where rownum <= last-first+1
7 ) x,
8 t
9 where x.dt = trunc(t.c1(+))
10 /
DT C
--------- -
01-JAN-04
02-JAN-04
03-JAN-04
04-JAN-04
05-JAN-04 a
06-JAN-04
07-JAN-04
08-JAN-04
09-JAN-04
10-JAN-04 b
11-JAN-04
12-JAN-04
13-JAN-04
14-JAN-04
15-JAN-04
16-JAN-04
17-JAN-04
18-JAN-04
19-JAN-04
20-JAN-04
21-JAN-04
22-JAN-04
23-JAN-04
24-JAN-04
25-JAN-04
26-JAN-04
27-JAN-04
28-JAN-04
29-JAN-04
30-JAN-04
31-JAN-04
31 rows selected.
Of course, you need not use the ( select trunc(last_day(max(c1))) last, trunc(min(c1),'mm') first from t ) if you KNOW the start/stop dates. You would just make the query be:
ops$tkyte@ORA9IR2> variable f varchar2(25);
ops$tkyte@ORA9IR2> variable s varchar2(25);
ops$tkyte@ORA9IR2> exec :f := '01-jan-2004'; :s := '31-jan-2004';
PL/SQL procedure successfully completed.
ops$tkyte@ORA9IR2>
ops$tkyte@ORA9IR2> select x.dt, t.c2
2 from (
3 select to_date(:f,'dd-mon-yyyy')+rownum-1 dt
4 from all_objects<b>
5 where rownum <= to_date(:s,'dd-mon-yyyy')-to_date(:f,'dd-mon-yyyy')+1</b>
6 ) x,
7 t
8 where x.dt = trunc(t.c1(+))
9 /
and you might even:
ops$tkyte@ORA9IR2> select x.dt, t.c2
2 from (
3 select to_date(:f,'dd-mon-yyyy')+rownum-1 dt
4 from all_objects
5 where rownum <= to_date(:s,'dd-mon-yyyy')-to_date(:f,'dd-mon-yyyy')+1
6 ) x,<b>
7 (select *
8 from t
9 where c1 between to_date(:f,'dd-mon-yyyy') and to_date(:s,'dd-mon-yyyy')
10 ) t</b>
11 where x.dt = trunc(t.c1(+))
12 /
Similar problem...
Neeti, February 20, 2004 - 11:41 am UTC
Hi Tom,
I have a similar problem. I have a report which accepts
a parameter in the form of YYYYQ and the requirement is
this parameter to be transformed into last day of that
quarter to use in a select statement.e.g. if I pass 19981
then this should be transformed into 03311998(last day of
first quarter)
This I use currently...
select last_day(to_date (substr( '19981', 1,4) ||
decode(substr('19981', 5,1),'1', '03', '2','06', '3'
,'09', '4', '12'), 'YYYYMM'))
from dual;
Is there a way I can improve this SQL..?
Thanks,
Vimal
February 20, 2004 - 1:17 pm UTC
select last_day(to_date( substr(:x,1,4) || (mod(:x,10)*3), 'yyyymm')) from dual;
is "shorter"
Need Some Help
A reader, June 21, 2006 - 9:15 am UTC
Hello Tom,
I need a query in this format since our fiscal year run from 10/1/xxxx to 9/30/xxxx and
then I need to get the total payment during that fiscal year.
How can I have something in this format..
Fiscal Start Fiscal End Total Payments
10/1/1986 9/30/1987 0.00
10/1/1987 9/30/1988 0.00
10/1/1988 9/30/1989 11,448.00
10/1/1989 9/30/1990 15,853.71
10/1/1990 9/30/1991 19,096.00
10/1/1991 9/30/1992 23,762.72
10/1/1992 9/30/1993 37,481.13
10/1/1993 9/30/1994 38,374.44
10/1/1994 9/30/1995 39,540.46
10/1/1995 9/30/1996 40,659.17
Thank you.l
June 22, 2006 - 10:43 am UTC
ok, good, I guess you should write one?
no create
no inserts
NO EXPLANATION of the inputs or outputs...
no look.