How to join between three tables using a subquery? - sql

I have 3 SQL tables:
tb1: name id and phone of student
tb2: courseName,courseNum
tb3: id,courseNum,grade
I need to find the name and courseName of student that their grade>80
I tried:
select * from tb1 where taz in(
select taz from tb3 where grade>80
)
and
select courseNum from tb2 where courseName in(
select * from tb3 where grade>80
)
It works but how can I join the 2 subquery?

Try using join as below:
SELECT *
FROM tb3 t3 INNER JOIN tb2 t2
ON t3.courseNum = t2.courseNum
INNER JOIN tb1 t1
ON t2.id = t1.id
WHERE t3.grade > 80

Try this :
SELECT c.name, b.courseName, a.grade
FROM tb3 a
JOIN tb2 b ON a.courseNum = b.courseNum
JOIN tb1 c ON a.id = c.id
WHERE a.grade > 80

Following query will give you the required result:
SELECT t1.Name, t2.CourseName, t3.grade from tb3
INNER JOIN tb2 t2 ON t3.CourseNum = t2.CourseNum
INNER JOIN tb1 t1 ON t1.id = t3.Id
where t3.grade > 80

SMA answer is true, but need little modification.
first: condition on second ON should be: t3.id = t1.id
second: we want name and courseName.
SELECT t1.name, t2.coursename
FROM tb3 t3 INNER JOIN tb2 t2
ON t3.courseNum = t2.courseNum
INNER JOIN tb1 t1
ON t3.id = t1.id
WHERE t3.grade > 80

Related

How do I look for non-matching values across 3 SQL tables?

I'm looking to do what I believe is a double-nested check across three tables, but have no idea how to do so.
I have Table1, Table2, and Table3.
All are tied by an ID and a "Longform" and "Shortform" in Table1:
I'm trying to find:
Entries whose IDs appear in Table2 that have the same Longform as those in Table3, but don't share the same Shortform.
This is about as far as I've gotten:
SELECT T2.Longform,T2.Shortform FROM(
SELECT Table1.Longform,Table1.Shortform,Table1.ID FROM OuterTable1.Table1
LEFT JOIN OuterTable2.Table2 on Table1.ID = Table2.ID)
WHERE Table2.ID IS NOT NULL) T2
;
I know I'm probably going to have to do another nested select, or a join, on Outertable3.Table3 but I'm not sure which... Or where...
Any help appreciated as always.
Try the following:
Select *
(
Select T1.*
from T2
inner join T1
on T1.ID = T2.ID
) as Tab
inner join
(
Select T1.*
from T3
inner join T1
on T1.ID = T3.ID
) as Tab2
on Tab.id = Tab2.id
and Tab.Longform = Tab2.Longform
and Tab.Shortform <> Tab2.Shortform
To get the longform join table1 to table2 or table3. Then use EXISTS to check in a subquery if the IDs of table1 are different but the longform is equal.
SELECT *
FROM table2 t21
INNER JOIN table1 t11
ON t11.id = t21.id
WHERE EXISTS (SELECT *
FROM table3 t32
INNER JOIN table1 t12
ON t12.id = t32.id
WHERE t12.id <> t11.id
AND t12.longform = t11.longform);
Assuming ID is unique in all three tables
Select t2.id,t2.shortform, t1.shortform AS shortformTab1, t2.longform
FROM table2 t2
JOIN table3 t3
ON t2.id = t3.id AND t2.longform = t3.longform
JOIN table1 t1
ON t2.id = t1.id AND t2.shortform != t1.shortform

sql union displays duplicates

image of what I want
I have tried the join on x or y and it didn't work, even the group by didn't work.
What almost gave me the result is the query below
SELECT A.Id ,A.AccNo ,A.Name ,B.Id ,B.AccNo1 ,B.AccNo2 ,B.Name
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo1
union
SELECT A.Id ,A.AccNo ,A.Name ,B.Id, B.AccNo1, B.AccNo2, B.Name,
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo2
After getting the query correct I want to show only the exceptions where there was no link between the tables and its kind of difficult if the T1.ID is repeated
You seem to want a left join:
select t1.*, t2.*
from table1 t1 left join
table2 t2
on t1.id in (t2.accno1, t2.accno2);
Try:
SELECT A.Id ,A.AccNo ,A.Name ,B.Id ,B.AccNo1 ,B.AccNo2 ,B.Name
from Table1 as A
left outer join Table2 as B
ON A.AccNo = (CASE WHEN A.AccNo = B.AccNo1 THEN B.AccNo1 ELSE B.AccNo2 END)
You may nest your original query, and then use max aggregate function with grouping :
SELECT Id ,AccNo ,Name, max(Id2) as Id2, max(Name2) as Name2,
max(AccNo1) as AccNo1, max(AccNo2) as AccNo2
FROM
(
SELECT A.Id ,A.AccNo ,A.Name ,B.Id Id2 ,B.AccNo1 ,B.AccNo2 ,B.Name Name2
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo1
union
SELECT A.Id ,A.AccNo ,A.Name ,B.Id Id2, B.AccNo1, B.AccNo2, B.Name Name2
from Table1 as A
left outer join Table2 as B on A.AccNo = B.AccNo2
) q
GROUP BY Id ,AccNo ,Name;
SQL Fiddle Demo
Do a LEFT JOIN to return the table1 values along with matching table2 values (where t2.accno2 = t1.accno):
select t1.*, t2.*
from table1 t1
left join table2 t2
on t1.accno = t2.accno2
Or, perhaps you want table2 values for matching accno1's as well?
select t1.*, t2.*
from table1 t1
left join table2 t2
on t1.accno in (t2.accno1, t2.accno2)
It this way to resolve:
SELECT
t1.id,
t1.accno,
t1.name,
(
SELECT DISTINCT
id
FROM
table2
WHERE
accno2 = t1.accno
),
(
SELECT DISTINCT
name
FROM
table2
WHERE
accno2 = t1.accno
),
(
SELECT DISTINCT
accno1
FROM
table2
WHERE
accno2 = t1.accno
),
(
SELECT DISTINCT
accno2
FROM
table2
WHERE
accno2 = t1.accno
) FROM
table1 t1
LEFT JOIN table2 t2 ON t1.accno = t2.accno1 OR t1.id = t2.id

How to join the table based on main table column value in SQL Server?

I have the following 3 tables:
main_table:
id,name,table_type
1a,sas,1
2a,saw,1
3a,sdd,2
inst_table
id,inst_name,rating
1a,sdsdf,3
2a,erer,4
indv_table
id,ind_name,rating
3a,gbgbg,3
5a,gff,4
How to join the subtables based on main_table column:'table_type'?
I.e., if main table column: table_type = 1, then it has to join with table:'inst_table' else table:'indv_table'
SELECT *
FROM main_table t1
INNER JOIN inst_table t2 ON T1.ID = T2.ID where t1.table_type=1
UNION ALL
SELECT *
FROM main_table T1
INNER JOIN indv_table T3 ON T1.ID = T3.ID where t1.table_type=2
You can left join both sub-tables to main_table:
proc sql;
select m.*, i.*, d.*
from main_table as m
left join inst_table as i on m.id=i.id and m.table_type = 1
left join indv_table as d on m.id=d.id and m.table_type ne 1
;
quit;

Combining INNER JOIN and LEFT JOIN

Edited
I'm not asking How to write good query but those 3 queries return same results.
Query 1
SELECT v1.id
FROM (
SELECT DISTINCT t1.id
FROM t1 LEFT JOIN t2 ON t1.id = t2.id
WHERE t2.id IS NULL
) v1 INNER JOIN (
SELECT DISTINCT t3.id
FROM t3 LEFT JOIN t4 ON t3.id = t4.id
WHERE t4.id IS NULL
) v2 ON v1.id = v2.id;
Query 2
SELECT DISTINCT t1.id
FROM (t1 LEFT JOIN t2 ON t1.id = t2.id)
INNER JOIN (t3 LEFT JOIN t4 ON t3.id = t4.id) ON t1.id = t3.id
WHERE t2.id IS NULL AND t4.id IS NULL;
Query 3
SELECT DISTINCT t1.id
FROM t1 LEFT JOIN t2 ON t1.id = t2.id
INNER JOIN t3 ON t1.id = t3.id LEFT JOIN t4 ON t3.id = t4.id
WHERE t2.id IS NULL AND t4.id IS NULL;
Queries are not hard coded by programmer but generate dynamically by user input.
For example when user inserts find id in t1 (but not in t2) and in t3 (but not in t4), his indention is Query 1. But currently my program generates Query 3 and it looks like OK. I'm wondering this query has a bug in some cases, so that should be changed like Query 2 or 1.
User input (shown above) is just example and converting user input to JOIN statement is difficult at last to me.
Thanks in advanced.
This is the original query:
SELECT v1.id
FROM (SELECT DISTINCT t1.id
FROM t1 LEFT JOIN t2 ON t1.id = t2.id
WHERE t2.id IS NULL
) v1 INNER JOIN
(SELECT DISTINCT t3.id
FROM t3 LEFT JOIN t4 ON t3.id = t4.id
WHERE t4.id IS NULL
) v2
ON v1.id = v2.id;
If I understand correctly, you want ids that are in t1 and t3, but not in t2 and t4.
I would express the second query as:
SELECT distinct t1.id
FROM t1 INNER JOIN
t3
on t1.id = t3.id LEFT JOIN
t2
on t1.id = t2.id LEFT JOIN
t4
on t1.id = t4.id
WHERE t2.id IS NULL AND t4.id IS NULL;
I read your original query as asking for "all ids in T1 which are in both T1 and T3 but not in T2 or T4". Is that correct? If so, my query would be:
SELECT DISTINCT t1.id
FROM t1
WHERE EXISTS (SELECT 1 FROM t3 WHERE t1.id = t3.id)
AND NOT EXISTS (SELECT 1 FROM t2 WHERE t1.id = t2.id)
AND NOT EXISTS (SELECT 1 FROM t4 WHERE t1.id = t4.id)
Not sure what the real objective is, nor which dbms is being targeted
-- oracle
SELECT id FROM ( SELECT id FROM t1 MINUS SELECT id FROM t2 ) a
INTERSECT
SELECT id FROM ( SELECT id FROM t3 MINUS SELECT id FROM t4 ) b
;
-- sql server
SELECT id FROM ( SELECT id FROM t1 EXCEPT SELECT id FROM t2 ) a
INTERSECT
SELECT id FROM ( SELECT id FROM t3 EXCEPT SELECT id FROM t4 ) b
;
SELECT c.id from (
SELECT t1.id
FROM t1 LEFT JOIN t2 ON t1.id = t2.id
WHERE t2.id IS NULL
UNION ALL
SELECT t3.id
FROM t3 LEFT JOIN t4 ON t3.id = t4.id
WHERE t4.id IS NULL
) c GROUP BY c.id HAVING count(*) >= 2
;
The next one is potentially quite efficient BUT has a caveat
-- conditions apply, assumes t2 and t4 cannot have ids not in t1 or t3 respectively
SELECT c.id from (
SELECT a.id from (
(SELECT ID FROM T1)
UNION ALL
(SELECT ID FROM T2)
) a GROUP BY a.id HAVING count(*) = 1
UNION ALL
SELECT b.id from (
(SELECT ID FROM T3)
UNION ALL
(SELECT ID FROM T4)
) b GROUP BY b.id HAVING count(*) = 1
) c GROUP BY c.id HAVING count(*) >= 2
;
Fiddles:
| Oracle
| SQL Server |
MySQL |

SQL Join multiple tables using where clause

I want to write a sql statement:
Select * FROM table1
inner join table2 AS t2
ON
inner join table3 AS t3
ON
inner join table4 AS t4
ON
Where FK_Client_ID = 4
All tables have the client ID in common. So Not sure what to do on the ON.
Will it be something like ON t2.FK_Client_ID = ...... not sure.
So I just want all the data from those tables that has FK_Client_ID in common.
Select *,
(Select FK_Client_ID from table2 where FK_Client_ID = t1.FK_Client_ID )As TID1,
(Select FK_Client_ID from table3 where FK_Client_ID = t1.FK_Client_ID )As TID2,
(Select FK_Client_ID from table4 where FK_Client_ID = t1.FK_Client_ID )As TID3
FROM table1 t1
Select * FROM table1 t1 inner join table2 t2
ON t1.FK_Client_ID = t2.FK_Client_ID
inner join table3 t3
ON t1.FK_Client_ID = t3.FK_Client_ID
inner join table4 t4
ON t1.FK_Client_ID = t4.FK_Client_ID
Where t1.FK_Client_ID = 4
Try this
Select * FROM table1 t1
inner join table2 AS t2
ON t2.FK_Client_ID = t1.FK_Client_ID
inner join table3 AS t3
ON t3.FK_Client_ID = t1.FK_Client_ID
inner join table4 AS t4
ON t4.FK_Client_ID = t1.FK_Client_ID
Where t1.FK_Client_ID = 4
if your foreign field name is "FK_Client_ID" and primary key in table1 is "Client_ID"
Select * FROM table1
inner join table2 AS t2
ON t2.FK_Client_ID = table1.Client_ID
inner join table3 AS t3
ON t3.FK_Client_ID = table1.Client_ID
inner join table4 AS t4
ON t4.FK_Client_ID = table1.Client_ID
Where table1.Client_ID = 4
Since you are using inner join no matter you join them with table1 or any other of them