Skip to Main Content

Oracle Database Discussions

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Droping Materialized View but preserve its local table - Oracle 9i

ExorNov 11 2015 — edited Nov 11 2015

Hello gurus,

How would one drop a materialized view in 9i but preserve the table?

Thank you,

This post has been answered by unknown-7404 on Nov 11 2015
Jump to Answer

Comments

susmita
Please clarify whar do you mean by 'first day' ?
Is it first day of the month with Active_Code ='K' ? Then what is your rule to mark
November 3rd -> 4 Ks and November 10th -> 1K.
gambro2
The first day is not the first day in a month, it's rather the first day in a series of occurances.
Maybe the following statement explains tjhe request a little bit better:
"Give me all K-groups and their length in days"

BR
Christian
hm
Are you looking for something like this?
--
-- Data:
with demo as
(
select 123 emp_id, TO_DATE('01.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS') working_day, '_' active_code from dual union all
select  123, TO_DATE('02.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), '_' from dual union all
select  123, TO_DATE('03.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('04.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('05.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('06.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), NULL from dual union all
select  123, TO_DATE('07.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), NULL from dual union all
select  123, TO_DATE('08.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('09.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), '_' from dual union all
select  123, TO_DATE('10.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('11.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), '_' from dual)
--
-- query
select emp_id,
       min(working_day) min_k,
       (select count(*)-1 from demo d where d.emp_id=emp_id and active_code='K' ) more_k
from demo
where active_code='K'
group by emp_id;
Edited by: hm on 04.11.2010 02:15
gambro2
Thanks, but this is not 100% what I expect.
The result of your query would be:

EMP_ID MIN_K MORE_K
123 03.11.2010 4

Whereas I would expect:

EMP_ID MIN_K MORE_K
123 03.11.2010 4
123 10.11.2010 1

The first block would be 4 days starting 3rd and ending at the 8th.
The second block would be 1 day only at the 10th.

BR
Christian

Edited by: gambro2 on Nov 4, 2010 2:30 AM
009
Hi,

Try this one
WITH T AS
(
	SELECT D.*, DECODE(LAG(ACTIVE_CODE,1,ACTIVE_CODE) OVER (ORDER BY WORKING_DAY), ACTIVE_CODE,1,0) TST
	FROM   DEMO D
	WHERE  TRIM(TO_CHAR(WORKING_DAY,'DAY')) NOT IN ('SATURDAY','SUNDAY')
	ORDER BY WORKING_DAY
), T2 AS
(
SELECT SUM(TST) OVER (PARTITION BY ACTIVE_CODE ORDER BY WORKING_DAY DESC)+1 TST2, T.*
FROM   T
ORDER BY WORKING_DAY)
SELECT * FROM T2
WHERE  ACTIVE_CODE = 'K' AND TST = 0;
P.S.: Still scope for improvement in the SQL, need some more time ;)

*009*
Frank Kulash
Answer
Hi, Christian,

Assumiung you have exactly one row for every working_day (where active_code is not NULL):
WITH	got_grp_num	AS
(
	SELECT	emp_id
	,	working_day
	,	active_code
	,       ROW_NUMBER ()
		        OVER ( PARTITION BY  emp_id
			       ORDER BY	     working_day
			     )
	      - COUNT ( CASE
			    WHEN  active_code = 'K'
			    THEN  1
			END
		      )	OVER ( PARTITION BY  emp_id
			       ORDER BY	     working_day
			     ) 	AS grp_num
	FROM	demo
	WHERE	active_code	IS NOT NULL
--	AND	...	-- Any filtering goes here
)
SELECT	  emp_id
,	  MIN (working_day)	AS first_day
,	  COUNT (*)		AS cnt
FROM	  got_grp_num
WHERE	  active_code	= 'K'
GROUP BY  emp_id
,	  grp_num
ORDER BY  emp_id
,         first_day
;
I'm guessing at the role emp_id plays in this problem.

The tricky part of this problem is getting a suitable value to GROUP BY.
When you have several consecutive 'K' rows, the difference between the ROW_NUMBER (counting non 'K' rows, but not weekends) and the number of preceding 'K' rows will be constant. That is what grp_num is. (One of the adjacent non-'K' rows also has the same grp_num, but that's okay; it will be discarded by the WHERE clause in the main query.)

Edited by: Frank Kulash on Nov 4, 2010 5:43 AM
Marked as Answer by gambro2 · Sep 27 2020
hm
Please try this:
-- Data:
with demo as
(
select 123 emp_id, TO_DATE('01.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS') working_day, '_' active_code from dual union all
select  123, TO_DATE('02.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), '_' from dual union all
select  123, TO_DATE('03.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('04.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('05.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('06.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), NULL from dual union all
select  123, TO_DATE('07.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), NULL from dual union all
select  123, TO_DATE('08.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('09.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), '_' from dual union all
select  123, TO_DATE('10.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('11.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), '_' from dual)
--
-- query:
select emp_id,
       min(working_day) min_k,
       count(*)
from demo
where active_code='K'
group by emp_id, to_char(working_day -1 ,'IW');
I don't exactly understand the requirements. Perhaps you have to change "working_day -2" in the group by clause.
It depends on the starting day of week you need. Please try "working_day -1" and "working_day -2" with your data.

Edited by: hm on 04.11.2010 03:12
gambro2
Dear all,

the results from your queries is always one block with 4 K-days.
However, I'd expect to have both "blocks" (block 1 = 3rd to 8th and block 2 = only the 10th).

I'd better do some real life explanation now. Sorry for not doing that earlier.
In this list the K days represent the days an employee has been on sick leave.
I don't want to count the number days in total for a year, but I need to know how often and for how many days the emp was on leave in a specific year/time periode.

BR
Christian
009
Have you checked the SQLs posted by me or Frank?


*009*
gambro2
Hi hm,

I have checked your statement, but it returned 3 days for the first block, where there should be 4.
Franks statement didn't give me the second block.
Or am I doing something wrong?

BR
Christian
Frank Kulash
Hi, Christian,
gambro2 wrote:
Hi hm,

I have checked your statement, but it returned 3 days for the first block, where there should be 4.
Franks statement didn't give me the second block.
This is the output I get from the query I posted and your sample data:
`   EMP_ID FIRST_DAY                  CNT
---------- ------------------- ----------
       123 03.11.2010 00:00:00          4
       123 10.11.2010 00:00:00          1
Post the correct results you want.
Or am I doing something wrong?
That depends on what you're doing.
Post the exact code you're running, even if you only copied it from this site. It's possible an editing error occurred.
hm
Again the query from my previous posting (see above), this time with result:
-- Data:
with demo as
(
select 123 emp_id, TO_DATE('01.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS') working_day, '_' active_code from dual union all
select  123, TO_DATE('02.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), '_' from dual union all
select  123, TO_DATE('03.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('04.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('05.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('06.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), NULL from dual union all
select  123, TO_DATE('07.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), NULL from dual union all
select  123, TO_DATE('08.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('09.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), '_' from dual union all
select  123, TO_DATE('10.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), 'K' from dual union all
select  123, TO_DATE('11.11.2010 00:00:00','DD.MM.YYYY HH24:MI:SS'), '_' from dual)
--
-- query:
select emp_id,
       min(working_day) min_k,
       count(*)
from demo
where active_code='K'
group by emp_id, to_char(working_day -1 ,'IW');
result:
emp_id      min_k     count(*)
----------------------------------
123     03.11.2010	4                                     
123     10.11.2010	1                                     
gambro2
Hi Frank,

I made a mistake with your statement. Now it looks as what I expect.
It only needs to work on my "real" table as well now.
Since your statement looks quite complex, would you help me understand what it's doing?

BR
Christian
Frank Kulash
Hi, Christian,

When you want to understand some complicated code, break it down into smaller, simpler pieces and make sure you understand what each of them does.
In this case start with the sub-query, got_grp_num. Run just the sub-query, with "SELECT * FROM got_grp_num" as the main query.
Are there parts of that which are too complicated to understand? Then break them down. for example, the computation for grp_num is (r - c), where r is a ROW_NUMBER expression and c is an analytic COUNT function. Display r and c separately.
Are they still too complicated to understand? Break them down more; display just the results of the CASE expression in c, for example.

I described the overall strategy in my first message. The idea is to find grp_num such that all the 'K' rows on consecutive work-days wilol have the same grp_num; then getting the results you want will just be a matter of getting the minimum date and the total number of rows in each group. My approach is to use the constant difference detween the count of rows and the count of 'K' rows to get that grp_num. When you have one row per day, look down a list of the row and count the total number, and also count the number of 'K's. When you have a series of consecutive 'K' rows, the difference between those two counts will be constant throughout the streak. Dispaly r, c and (r - c), and you'll see what I mean. The actual grp_num ihas no great meaning, just the fact that it is constant throughout the streak.
Aketi Jyuuzou
I like tabibitosan method B-)
1007478
with demo(working_day,active_code) as(
select TO_DATE('01.11.2010','DD.MM.YYYY'),'_' from dual union
select TO_DATE('02.11.2010','DD.MM.YYYY'),'_' from dual union
select TO_DATE('03.11.2010','DD.MM.YYYY'),'K' from dual union
select TO_DATE('04.11.2010','DD.MM.YYYY'),'K' from dual union
select TO_DATE('05.11.2010','DD.MM.YYYY'),'K' from dual union
select TO_DATE('06.11.2010','DD.MM.YYYY'),NULL from dual union
select TO_DATE('07.11.2010','DD.MM.YYYY'),NULL from dual union
select TO_DATE('08.11.2010','DD.MM.YYYY'),'K' from dual union
select TO_DATE('09.11.2010','DD.MM.YYYY'),'_' from dual union
select TO_DATE('10.11.2010','DD.MM.YYYY'),'K' from dual union
select TO_DATE('11.11.2010','DD.MM.YYYY'),'_' from dual)
select min(working_day) as MIN_K,count(*) as MORE_K
from (select working_day,active_code,
       Row_Number() over(order by working_day)
      -Row_Number() over(partition by active_code
                         order by working_day) as gap
      from demo
      where active_code is not null)
where active_code = 'K'
group by gap
order by min(working_day);

MIN_K     MORE_K
--------  ------
10-11-03       4
10-11-10       1
gambro2
Thanks all. I finally got it working.
Now I will have to take the time to understand why...

BR
Christian
1 - 16
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Dec 9 2015
Added on Nov 11 2015
2 comments
824 views