How to check duplicate value - sql

I have two tables:
Table Tab1 ( Col1, Col2 )
Table Tab2 ( Col1, Col2 )
I want to check in the table Tab2 Col2 is there any same value with the table Tab1 in column Col2.
How to do that?

Using EXISTS
SELECT t2.col2
FROM TABLE2 t2
WHERE EXISTS (SELECT NULL
FROM TABLE1 t1
WHERE t1.col2 = t2.col2)
Using IN
SELECT t2.col2
FROM TABLE2 t2
WHERE t2.col2 IN (SELECT t1.col2
FROM TABLE1 t1)
Using JOIN:
SELECT DISTINCT t2.col2
FROM TABLE2 t2
JOIN TABLE1 t1 ON t1.col2 = t2.col2

Related

inserting into a table records from another table with a condition

Let's say I have two tables t1 and t2.
t1 has two integer cols col1 (primary) and col2
t2 has two cols a foreign key of t1.col1 and t2.col2
I want to do the following
Retrieve only the records where t1.col2 is unique OR if t1.col2 is duplicate only those if t2.col2 is not null.
Insert the above records into another summary table, let's say t3
This is what I tried:
insert into t3 (col1,col2)
select col1, col2
from t1
where t.col1 in (select A.col1 from t1 as A
group by 1
having count(*) > 1
union
select col1, col2
from t1, t2
where t.col1 in (select A.col1 from t1 as A
group by 1
having count(*) > 1
and t2.col2 is not null;
While the 'union qry' works on its own, the insert is not happening.
Any ideas or any other efficient way to achieve this please
You can select the records you want using:
select t1.*
from (select t1.*, count(*) over (partition by col2) as cnt
from t1
) t1
where cnt = 1 or
exists (select 1 from t2.col1 = t1.col1 and t2.col2 is null);
The rest is just an insert.

Using a subquery for IN clause Oracle

I am having some trouble using a subquery for the IN clause of a query.
Hard-coding the IN .. values allows the query to execute quickly, but using a subquery slows everything down. Is there a way to speed this query up?
SELECT col1, col2, col3 FROM table1
WHERE ...
and col1 in (SELECT col1 FROM table2)
...
*The values for the IN clause will be a list of strings
SELECT col1, col2, col3 FROM table1
WHERE ...
and col1 in ('str1', 'str2', 'str3', ...)
...
The above works fine.
EDIT:
I think I was oversimplifying the problem. The query I am trying to execute looks like this:
SELECT col1, col2, col3, ...
FROM table1 t1, table2 t2
WHERE t1.col1 IN (SELECT col FROM table3)
and t1.col2 < 50
and t2.col3 = t1.col3
...
You cant write select * from . If you give select * from, it doesnot understand which column to compare with from table2. Use the column name you need.
SELECT * FROM table1
WHERE ...
and col1 in (SELECT col1 FROM table2)
...
Use JOIN instead,
and keep an index defined on table1.col1 or table2.col3 or table1.col3 or table3.col :
SELECT col1, col2, col3, ...
FROM table1 t1
INNER JOIN table2 t2 on ( t2.col3 = t1.col3 )
INNER JOIN table3 t3 on ( t1.col1 = t3.col )
WHERE t1.col2 < 50;
Never use commas in the FROM clause. Always use proper, explicit, standard JOIN syntax. You should write the query as:
SELECT col1, col2, col3, ...
FROM table1 t1 JOIN
table2 t2
ON t2.col3 = t1.col3
WHERE t1.col1 IN (SELECT col FROM table3) AND
t1.col2 < 50;
I would write this using EXISTS, rather than IN:
SELECT col1, col2, col3, ...
FROM table1 t1 JOIN
table2 t2
ON t2.col3 = t1.col3
WHERE EXISTS (SELECT 1 FROM table3 t3 WHERE t1.col1 = t3.col) AND
t1.col2 < 50;
The filtering is all on table1; however, the columns are being compared with inequalities. I would try the following indexes: table2(col3), table1(col2, col1), and table3(col).

SQL-conditional joins

I have a requirement to join two tables Conditionally.
For Ex:
T1
--Col1
--Col2
--Col3
T2
--Col1
--Col2
--Col3
Join T1 and T2 on Col1 from both tables, If Col1 is NULL then join T1 and T2 on Col2 from both tables.
How to achieve this?
you can use a query like below, which uses case condition in join crtieria
select *
from
t1 join t2
on
case
when (t1.col1 is NULL or t2.col1 is NULL)
then t1.col2
else t1.col1
end
=
case
when (t1.col1 is NULL or t2.col1 is NULL)
then t2.col2
else t2.col1
end
Your conditions are ambiguous. What if col1 is NULL in only one table?
In any case, you can specify the logic as something like:
select . . .
from t1 join
t2
on (t1.col1 = t2.col1) or
( (t1.col1 is null or t2.col1 is null) and t1.col2 = t2.col2)
The first condition will fail if either column is NULL.
SELECT
*
FROM
T1 INNER JOIN T2
ON T1.COL1=T2.COL1 OR T1.COL2=T2.COL2
I am using Inline view. Check this query.
select * from
(select t1.col1,t1.col2,t1.col3 from table1 t1)q1,
(select t2.col1,t2.col2,t2.col3 from table1 t2)q2
where t1.col1=t2.col1 or t1.col2=t2.col2;
Thanks All :)
I just tot of the below query, let me know if this works.
Select * from
(select col1, col2, col3, coalesce(col1, col2) as join_key)q1,
(select col1, col2, col3, coalesce(col1, col2) as join_key)q1,
where q1.join_key = q2.join_key

Delete Rows in a table Based on column value in third table

I have three tables Table1, Table2 and Table3 and the following query which deletes rows in Table1
delete from Table1
where EXISTS
(select (1) from Table2
where Table1.col1=Table2.col1
AND Table1.col2=Table2.col2
AND Table1.col3=(select **Table3.col3 from Table3** inner join Table2 on Table3.col1=Table2.col1)
Is this query correct? If not, how to use a third table inside the where condition?
Edit : Also, please explain how to rewrite the query if we want to delete the rows from table2 which itself is joined with table3?
Here's one way to do it:
delete from table1
where (col1, col2, col3) in (
select t1.col1, t1.col2, t1.col3
from table1 t1
join table2 t2 on t1.col1 = t2.col1 and t1.col2 = t2.col2
join table3 t3 on t1.col3 = t3.col3 and t2.col1 = t3.col1
);
SQL Fiddle Demo
Or using EXISTS might be faster:
delete table1
where exists (
select *
from table2
join table3 on table2.col1 = table3.col1
where table1.col3 = table3.col3 and
table1.col1 = table2.col1 and
table1.col2 = table2.col2);

How to get the following join query

How to get the following join
input:
table1: table2:
col1 Col1 col2 col3
A A 1 2
B B 4 5
C
output:
col1 col2 col3
A 1 2
B 4 5
c - -
SELECT t1.col1, t2.col2, t2.col3
FROM table1 t1
LEFT JOIN table2 t2 ON t1.col1=t2.col1
;
You can do this using full outer join:
select coalesce(t1.col1, t2.col1), t2.col2, t2.col3
from table1 t1 full outer join
table2 t2
on t1.col1 = t2.col1;
This returns all rows from both tables, even those that don't match (it is a left and right outer join at the same time).
You can also do this using union all and aggregation:
select col1, max(col2) as col2, max(col3) as col3
from ((select col1, NULL as col2, NULL as col3
from table1
) union all
(select col1, col2, col3
from table2
)
) t
group by col1;
select t1.col1, t2.col2, t2.col3
from table1 t1
left outer join table2 t2
on t1.col1 = t2.col1
Maybe something like this if you wan't the '-'
SELECT t1.col1, coalesce(t2.col2,'-') as col2, coalesce(t2.col3,'-') as col3
FROM table1 t1
LEFT JOIN table2 t2 ON t1.col1=t2.col1
See my sqlfiddle
create table table1(
col1 char(1)
);
insert into table1 values('A');
insert into table1 values('B');
insert into table1 values('C');
create table table2(
col1 char(1),
col2 int,
col3 int
);
insert into table2 values('A',1,2);
insert into table2 values('B',4,5);
select
t1.col1,
coalesce(t2.col2,'-'),
coalesce(t2.col3,'-')
from
table1 t1
left join table2 t2 on t1.col1=t2.col1
;
http://sqlfiddle.com/#!2/bc768/2
You need to do an outer join
SELECT *
FROM table1 t1,
table2 t2
WHERE t1.col1 = t2.col1(+)