Conditional comparison - plsql

Given one table T1 with 100 rows and A,B,C,D as columns .
I need to check that C and D are equal in case A and B are both 1. Could anyone provide me the SQL code for this?

If it's a SQL then maybe this is what you need:
select *
from T1
where (A=1 and B=1 and C=D) or (a<>1) or (b<>1)
but if it's plsql then:
DECLARE
cursor c is
select A,B,C,D from T1;
BEGIN
FOR r IN c LOOP
IF r.A = 1 AND r.B = 1 THEN
IF r.C = r.D THEN
dbms_output.put_line('YES!!!');
ELSE
dbms_output.put_line('Oh no ...');
END IF;
END IF;
END LOOP;
END;

Related

How to implement CASE SELECT in WHERE clause

I have two tables T1 and T2
Senario 1:
Table T1 has a Column C1 with values terminal1, terminal2, terminal3
Select C1 from T1
Terminal1
Terminal2
Terminal3
Table T2 has a Column C2 with values terminal1, terminal2
Select C2 from T2
Terminal1
Terminal2
Senario 2
Table T2 can sometimes be null
Select C2 from T2
(null)
(null)
My Output has to be
When Senario 1 Then
Terminal1
Terminal2
When Senario 2 Then
Terminal1
Terminal2
Terminal3
i.e when table T1 and T2 have common values I want only the matching values
and
when Table T2 has null values then I want all the values
from table T1
It seems that what you need is a left outer join. Outer joins allow us to conditionally join tables.
This version of your query will return STORE_TERMINAL_LOCATION for all the rows in SP_RETAIL_TRANSACTION and matching values only of SP_TEMP_LOOKUP.AIRPORT_TERMINAL.
SELECT DISTINCT A.STORE_TERMINAL_LOCATION, B.AIRPORT_TERMINAL
FROM SP_RETAIL_TRANSACTION A,
left outer join SP_TEMP_LOOKUP B
on A.STORE_TERMINAL_LOCATION = B.AIRPORT_TERMINAL
Your question needs some proper formatting and elaborate more on the problem you are facing. I assume, you need a statement, which shows what values intersect, and if they do not - show only tables A. For that clause, you need to use inner joins and case structure. For example:
select
ter."HEATHROW_TERMINAL",
case
when lok."HEATHROW_TERMINAL" is not null then
'Terminal is in both tables'
else
'Terminalis only in main table'
end terminal_state
from
test_terminal_v ter,
test_lookup_v lok
where
ter."HEATHROW_TERMINAL" = lok."HEATHROW_TERMINAL"(+)
wheres, test_terminal_v (A) has values "5","4","2","3" and test_lookup_v (B) has "4","2","3".
Hope it helps.
After comments: there are several approaches. 1) You can use temporary tables. Create one and the code is:
begin
insert into test_term_tmp
select
ter.terminal
from
test_terminal_v ter,
test_lookup_v lok
where
ter.terminal = lok.terminal;
if sql%rowcount = 0 then
insert into TEST_TERM_TMP
select
ter.terminal
from
test_terminal_v ter;
end if;
end;
or 2) use types, for example:
declare
type t_term_tab is table of number index by binary_integer;
l_term t_term_tab;
l_i number := 1;
begin
for l_rec1 in (
select
ter.terminal
from
test_terminal_v ter,
test_lookup_v lok
where
ter.terminal = lok.terminal)
loop
l_term(l_i) := l_rec1.terminal;
l_i := l_i + 1;
end loop;
if l_term.first is null then
l_i := 1;
for l_rec2 in (
select
ter.terminal
from
test_terminal_v ter)
loop
l_term(l_i) := l_rec2.terminal;
l_i := l_i + 1;
end loop;
end if;
end;
Test the performance, based on your data. Hope it helps.
Thank you Guys, I think I found the answer
select distinct T1.C1, T2.C2
from T1 ,T2
where T2.C2=T1.C1 or T2.C2 is null;
Where in my code it was
select distinct A.STORE_TERMINAL_LOCATION,B.AIRPORT_TERMINAL
from SP_RETAIL_TRANSACTION A,SP_TEMP_LOOKUP B
where B.AIRPORT_TERMINAL=A.STORE_TERMINAL_LOCATION or B.AIRPORT_TERMINAL is null;

how to prevent duplicate values while using inner for loop in oracle plsql?

I am passing c1 value as param to the c2,c3 cursor's , so i am getting duplicate values and how to write better than this code using plsql code?
Declare
cursor cur1;
cursor cur2
is
select * from
where param=c1.param;
cursor cur3
is
select * from
where param=c1.param;
Begin
for c1 loop
for c2(c1.param)
dbms_output(deptno||' '||dname);
for c3(c1.param)
dbms_output(deptno||' '||dname);
end loop;
end loop;
end loop;
End;
So , i am getting duplicate values
deptno dname
10 a
20 b
30 c
10 a
20 b
30 c
Expected output as
deptno dname
10 a
20 b
30 c
can you please help me?
Sounds like you may want a UNION:
Declare
cursor cur1;
cursor cur2 is
select * from X
where param=c1.param
union
select * from Y
where param=c1.param;
Begin
for c1 loop
for c2(c1.param)
dbms_output(deptno||' '||dname);
end loop;
end loop;
End;
(I haven't fixed your invalid code above - presumably your real code is correct or it wouldn't have run at all.)
You probably don't need even 2 cursors, you could do something like:
Declare
cursor cur is
select * from X
where param in (select ...)
union
select * from Y
where param in (select ...)
Begin
for c2 in cur loop
dbms_output(deptno||' '||dname);
end loop;
End;
you can use inner join to avoid cursor looping.
use distinct keyword to get distinct value.
user of rownum keword to get only one row.
eliminate duplicate by group by clause.

Decode with alias name in cursor

I want to use decode function in cursor with alias names to avoid column ambiguity so i used below approach.
I have code such as:
declare
cl number;
cursor c is
select c1.rowid,c1.col1,
DECODE(c1.col2, 'XYZ', c1.col3, 10) cl
from table1 d,table2 c1 where c1.process_id=13525 and d.col3(+)=cl;
begin
for rec in c
loop
dbms_output.put_line(NVL(rec.cl,'-1'));
end loop;
end;
In this, when i will fire query by removing condition 'and d.col3(+)=cl' it will retrieve me data with the value of 'cl' . But when i assign this condtion it will not retrive data and not go in for loop of cursor.I have a matching data in d.col3.
Suppose if i will get cl as 5 then it is also present in d.col3 then it should give me data i did this because i need to remove duplicate records.Because with that single condition i will get duplicate records.Here col3 in d table is as primary key.
So i am not getting why it will not go in for loop as it gets value from query.
You can't use alias in WHERE clause: Using an Alias in a WHERE clause
In such cases, a sub-query or a CTE might help. Something like that (untested!):
with V as (
select c1.rowid rid, ,c1.col1, c1.process_id,
DECODE(c1.col2, 'XYZ', c1.col3, 10) cl
from table2 c1)
select V.rid, V.col1, V.cl from table1 d,V
where V.process_id=13525 and d.col3(+)=V.cl;
After getting suggestion that using WITH clause, My approach to retrieve data through DECODE() using alternative table name is:
declare
cl number;
cursor c is
with V as (
select c1.process_id,
DECODE(c1.col2, 'BANDM', c1.col3, 10) cl
from table2 c1)
select c1.rowid rid,c1.col1, V.cl from table1 d,V,table2 c1
where V.process_id=1
and d.col3(+)=V.cl
and c1.col3=V.cl;
begin
for rec in c
loop
dbms_output.put_line(NVL(rec.rid,'-1'));
dbms_output.put_line(NVL(rec.cl,'-1'));
end loop;
end;
Another solution without WITH clause is :
declare
c2 number;
cursor c is
select c1.process_id
c1.rowid,
c1.col1,
DECODE(c1.col2, 'BANDM', c1.col3, 10) as c2
from table1 d,
table2 c1
where c1.process_id=1
and d.col3(+) = DECODE(c1.col2, 'BANDM', c1.col3, 10);
begin
for rec in c
loop
dbms_output.put_line(NVL(rec.rid,'-1'));
dbms_output.put_line(NVL(rec.c2,'-1'));
end loop;
end;

How to concatinate values of two columns and insert concatinated values into one column of another table

Table : SOURCE (Label,SerialNo )
Rows:
a 1
b 2
c 3
Target table : Target (Concat)
Expected Rows
1a
2b
3c
This needs to be achieved through procedure.
Hi this procedure should satisfy your query.Please let me know if you want anything else. Thanks
CREATE OR REPLACE
PROCEDURE query_answered
AS
BEGIN
FOR rec IN
( SELECT sr_no||' '||name AS combined_value FROM avrajit
)
LOOP
INSERT INTO av_dup
(department
) VALUES
(rec.combined_value
);
COMMIT;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line('Error captured'||' '||sqlerrm);
END query_answered;
----------------------------------
OUTPUT
----------------------------------
BEGIN
query_answered();
END;

oracle 10g pl/sql conditional for loop select

Is it possible to do something like this in PL/SQL in 10g?
if user_is_goat = 1 then
for item_rec in (select * from pricing_for_goats)
else
for item_rec in (select * from pricing_for_non_goats)
end if;
loop
.
.
end loop;
It seems that when oracle sees "for rec in select * from dual" it expects "loop" to immediate follow. My code in the loop is many lines and I don't want to have to maintain 2 copies of it.
Try query below, this will check if variable user_is_goat = 1 and returns data from for_goats else it will return from for_non_goats
for item_rec in
(
select * from pricing_for_goats where user_is_goat = 1
union
select * from pricing_for_non_goats where user_is_goat <> 1
)
loop
.....
.....
end loop;

Resources