Helena Marková, June 06, 2005 - 5:24 am UTC
Thanks!
Dave, June 06, 2005 - 7:41 am UTC
This was the answer I was looking for... It works great!
Short and sweet - but where did it come from?
Glenn Feiner, June 06, 2005 - 10:10 am UTC
The only place I can see the use of the "with" clause is for materilized views. Is this the same clause? I'm tryig to understand your thought process and problem solving stragedy, how did you think to use this for this problem?
June 06, 2005 - 11:02 am UTC
why do you think they are only used in materialized views?
they are part of SQL and very useful for writing any query.
understanding with clause
Parag Jayant Patankar, June 07, 2005 - 9:46 am UTC
Hi Tom,
I am trying to understand with clause in SQL. I know with clause can be used for recursive and factoring reasons.But I am having very little practical knowledge of using it. Can you explained me your answer to question
ops$tkyte@ORA9IR2> with categories
2 as
3 (
4 SELECT CASE
5 WHEN l = 1 THEN 'HOURS < 04.'
6 WHEN l = 2 then '04 < HOURS < 08'
7 WHEN l = 3 THEN '08 < HOURS < 16'
8 WHEN l = 4 tHEN '16 < HOURS < 24'
9 WHEN l = 5 THEN '24 < HOURS < 40'
10 ELSE '40 < HOURS'
11 END CAT
12 from (select level l from dual connect by level <= 6)
13 )
14 select * from categories
15 /
Q1. more about concept of with clause and why you have choosen to use in this SQL then may be another available options ?
Q2. with "with clause" can I give any name or only table name i.e. table name categories ?
Q3. How you have created categories table and how many rows it is having it, is it more than 6 ?
regards & thanks
pjp
June 07, 2005 - 12:47 pm UTC
q1) think of it like a subroutine, it is a way of writing "modular sql". I used it over an inline view for that reason in this case.
with q1
as
( nasty query ),
q2
as
( another query ),
q3
as
( yet another )
select *
from q1, q2, q3
where ....
rather then
select *
from (nasty query ),
(another one),
(yet another )
where ....
q2) with <YOUR_NAME_HERE> as (query), <YOUR_OTHER_NAME_HERE> as (query)...
q3) it is precisely 6 in this example.
with clause
Jon, June 07, 2005 - 10:51 am UTC
Does this help understand "with"?
[pre]
with sub as
(select * from v$session)
select * from sub
[/pre]
is the same as:
[pre]
select sub.*
from (select * from v$session) sub
[/pre]
I get the same query plan in my db too.
June 07, 2005 - 12:59 pm UTC
but you might not get the same plan....
WITH CARTESIAN
Duke Ganote, August 05, 2005 - 2:45 pm UTC
This question got me to re-thinking a problem I'd solved (reluctantly) procedurally back in 2003. The issue: I have to display sales for every month and product, with zero value for any month/product combination with no sales. The WITH clause helped me extract the in-line view so I solved in pretty quickly this time:
create table MONTHS as
select level AS MONTH from dual connect by level <= 12
/
create table PRODUCTS as
select chr(64+level) AS PRODUCT from dual connect by level <= 5
/
create table SALES ( MONTH number, PRODUCT varchar2(4), AMT number
constraint SALES_PK ( month, product ) )
/
insert into SALES values ( 6, 'B', 750 )
/
insert into SALES values ( 8, 'D', 900 )
/
with CARTESIAN as
(
select MONTH, PRODUCT
from MONTHS cross join PRODUCTS
)
select C.PRODUCT, C.MONTH, COALESCE(S.AMT,0) SALES_AMT
from CARTESIAN C left join SALES S
on ( C.product = S.product
and C.month = S.month )
order by C.product, C.month
/
PROD MONTH SALES_AMT
---- ---------- ----------
A 1 0
A 2 0
A 3 0
A 4 0
A 5 0
A 6 0
A 7 0
A 8 0
A 9 0
A 10 0
A 11 0
A 12 0
B 1 0
B 2 0
B 3 0
B 4 0
B 5 0
B 6 750
B 7 0
B 8 0
B 9 0
B 10 0
B 11 0
B 12 0
C 1 0
C 2 0
C 3 0
C 4 0
C 5 0
C 6 0
C 7 0
C 8 0
C 9 0
C 10 0
C 11 0
C 12 0
D 1 0
D 2 0
D 3 0
D 4 0
D 5 0
D 6 0
D 7 0
D 8 900
D 9 0
D 10 0
D 11 0
D 12 0
E 1 0
E 2 0
E 3 0
E 4 0
E 5 0
E 6 0
E 7 0
E 8 0
E 9 0
E 10 0
E 11 0
E 12 0
60 rows selected.
partitioned outer join
A reader, August 30, 2005 - 9:53 am UTC
just as i read this in the docu a few days before. with oracle 10.1 there is a new feature called "partitioned outer join" for creation of dense data (documentation can be found in the datawarehousing guide, chapter 21: sql for analysis and reporting, data densification for reporting).
syntax:
SELECT .....
FROM table_reference
PARTITION BY (expr [, expr ]... )
RIGHT OUTER JOIN table_reference
SELECT .....
FROM table_reference
LEFT OUTER JOIN table_reference
PARTITION BY {expr [,expr ]...)
quick and dirty example:
show me customer salaries per month
TEST @ test101 SQL>desc sales
Name Null? Typ
----------------------------------------------------- -------- ------------------------------------
CUSTOMER_ID NUMBER
SALARY_DATE DATE
AMOUNT NUMBER
TEST @ test101 SQL>select * from sales;
CUSTOMER_ID SALARY_D AMOUNT
----------- -------- ----------
1 17.01.05 12500
1 13.05.05 7600
2 04.03.05 9900
2 22.04.05 3000
1 22.01.05 500
1 05.03.05 100
6 Zeilen ausgewählt.
Abgelaufen: 00:00:00.01
TEST @ test101 SQL>edit
file afiedt.buf wurde geschrieben
1 select customer_id, last_day (months.first) last_monthday, sum (nvl (amount, 0)) amount
2 from sales
3 partition by (customer_id)
4 right outer join (select add_months (trunc (sysdate, 'YYYY'), level - 1) first
5 from dual
6 connect by level <= 6
7 ) months
8 on (trunc (salary_date, 'MM') = months.first)
9* group by customer_id, months.first
TEST @ test101 SQL>/
CUSTOMER_ID LAST_MON AMOUNT
----------- -------- ----------
1 31.01.05 13000
1 28.02.05 0
1 31.03.05 100
1 30.04.05 0
1 31.05.05 7600
1 30.06.05 0
2 31.01.05 0
2 28.02.05 0
2 31.03.05 9900
2 30.04.05 3000
2 31.05.05 0
2 30.06.05 0
12 Zeilen ausgewählt.
Abgelaufen: 00:00:00.02
well done, oracle! :)
cannot use WITH
A reader, August 30, 2006 - 5:04 am UTC
Hi
I am running 8.1.7.4 and I have a similar problem as the first post.
I have this query to find out log switches per hour in the last 7 days (number of days ca change, 7 or 30)
select to_char(FIRST_TIME, 'YYYY-MM-DD HH24') DIA_HORA,
to_char(FIRST_TIME, 'DAY') DIA_SEMANA,
count(*)
from v$log_history
where FIRST_TIME between trunc(sysdate)-7 and trunc(sysdate)
group by to_char(FIRST_TIME, 'YYYY-MM-DD HH24'), to_char(FIRST_TIME, 'DAY');
This shows something like
2006-08-29 09 TUESDAY 1
2006-08-29 11 TUESDAY 1
2006-08-29 14 TUESDAY 1
2006-08-29 16 TUESDAY 1
2006-08-29 17 TUESDAY 2
.....
What i need is
2006-08-29 09 TUESDAY 1
2006-08-29 10 TUESDAY 0
2006-08-29 11 TUESDAY 1
2006-08-29 12 TUESDAY 0
2006-08-29 13 TUESDAY 0
2006-08-29 14 TUESDAY 1
2006-08-29 15 TUESDAY 0
2006-08-29 16 TUESDAY 1
2006-08-29 17 TUESDAY 2
I cannot use the WITH since that works from 9i upwards, what can I do in 8.1.7?
Cheers
August 30, 2006 - 8:45 am UTC
you can always use inline views.
instead of
with q
as
(select ...)
select * from q;
you can:
select * from (select ...)
actually, ctl-f for "understanding with clause" on this page, we already discussed it.