SQL Multiple Joins Query - sql

Here I have two tables committee_colleges and colleges.
Structure of tables is something like this
committee_colleges
committeeCollegeId collegeId committeeMemberId
1 2 1
2 2 2
3 3 2
I am storing committeeMemberId from committeeMember table.And one college can have multiple committee Members.How can I wite a query to display only the colleges assigned to specific committee Member.
For Example,if committeeMember by id=2 has logged in I want to display colleges by id=2,3.
In college table I have like this,
collegeId typeName
1 AICTE
2 NCTE
3 NTCS
This is Committee Member table
committeeMemberId name
1 xyz
2 abc
Now I am writing something like this,but i know its wrong because I dont know how to take it from College table since I am displaying College details.
SELECT cc.committeeCollegeId as committeeCollegeId,
c.collegeId as collegeId,
cc.committeeMemberId as committeeMemberId
FROM committee_college as cc
left outer join College as c
on cc.collegeId = c.collegeId
where cc.committeeMemberId=:committeeMemberId
order by cc.committeeCollegeId asc
Can anyone tell how to display colleges based on its assignment to particular committeeMember?

You were close, you need INNER JOIN instead of LEFT JOIN:
SELECT DISTINCT C.typeName --<<== put here all the columns that you want in output
FROM committee_colleges CC
INNER JOIN college C
ON C.collegeId = CC.collegeId
WHERE CC.committeeMemberId = 2 --<<== your input parameter
EDIT: added DISTINCT
Hope it helps.

You can use below sql statement for the same
DECLARE #committeeMemberId INT = 2 -- Id of Committee member
;WITH CTE_MemberCommittee AS
(
SELECT CollegeId
FROM committee_colleges
WHERE committeeMemberId = #committeeMemberId
)
SELECT collegeId, typeName
FROM college
WHERE collegeId IN (SELECT CollegeId FROM CTE_MemberCommittee)

You can use simple inner join for that,
If you want collegename based on memberId use following query,
select a.collegeid,a.typeName from
college a, committee_colleges b, committe_member c
where a.collegeid = b.collegeid and
b.committeememberid = c.committeeMemberId
and c.committeeMemberId = '2'
If you want collegename based on committemember name then use following query,
select a.collegeid,a.typeName from
college a, committee_colleges b, committe_member c
where a.collegeid = b.collegeid and
b.committeememberid = c.committeeMemberId
and c.Name = 'xyz'
Hope it will help.

try this:
DECLARE #LoginCommitteeMemberId INT=2
SELECT t2.Name AS MemberName,
t3.TypeName AS CollageName
FROM committee_college t1
INNER JOIN Committee_Member t2
ON t1.committeeMemberId = t2.committeeMemberId
INNER JOIN College as t3
ON t1.collegeId = t3.collegeId
WHERE t1.committeeMemberId = #LoginCommitteeMemberId

Related

Is it possible to replace content from multiple foreign keys when doing a query?

I have the following tables:
TABLE PLAYER
id | name
1 | A
2 | B
3 | C
4 | D
TABLE PAIRINGS
id | player_a | player_b
1 | 3 |1
2 | 2 |4
Both columns in table Pairings are foreign keys to column id of table player.
My problem is, I would like to avoid making a query from code every time I want to know which is my player's name (like, Select name From Player Where Id = pairings.player_a). I have thought about adding Name as an extra columnd to Pairings table, but that would denormalize it.
Instead, it would be nice if I could get the names in just one query, like:
RESULT
player_a | player_b
C | A
B | D
Is it this possible? Thanks so much in advance.
You may join the PAIRINGS table to the PLAYER table, twice:
SELECT
p1.name AS player_a,
p2.name AS player_b
FROM PAIRINGS pr
INNER JOIN PLAYER p1
ON pr.player_a = p1.id
INNER JOIN PLAYER p2
ON pr.player_b = p2.id;
Demo
Don't do it! One of the points of using a relational database is that data is stored in only one place. That is a big convenience. Of course, there are exceptions, but these exceptions should have firm reasons.
In this case, just define a view:
CREATE VIEW vw_pairings AS
SELECT p.*, pa.name AS player_a_name,
pb.name AS player_b_name
FROM PAIRINGS p JOIN
PLAYER pa
ON p.player_a = pa.id JOIN
PLAYER pb
ON p.player_b = pb.id;
When you query from the view, you will see the names, along with all the other information in the PAIRINGS table.
Hope can help you
Select * Into #PLAYER From (
Select 1 [ID], 'A' [Name] Union All
Select 2 [ID], 'B' [Name] Union All
Select 3 [ID], 'C' [Name] Union All
Select 4 [ID], 'D' [Name]
) A
Select * Into #PAIRINGS From (
Select 1 [ID], 3 [PLAYER_A], 1 [PLAYER_B] Union All
Select 2 [ID], 2 [PLAYER_A], 4 [PLAYER_B]
) A
Select
P.ID, A.NAME, B.NAME
From #PAIRINGS P
Left Join #PLAYER A On A.ID = P.PLAYER_A
Left Join #PLAYER B On B.ID = P.PLAYER_B
You can create view, for avoid making query
Example
Create View vwPAIRINGS As
Select
P.ID, A.NAME, B.NAME
From #PAIRINGS P
Left Join #PLAYER A On A.ID = P.PLAYER_A
Left Join #PLAYER B On B.ID = P.PLAYER_B
After that, just select usual
Select * from vwPAIRINGS

How to get the unmatched records from two tables using Joins

I have two tables one is teacher and another is Department which is mentioned below.
Teacher Table
Id Name
1 xyz
2. Gjd
3. Dftr
4 dhdk
Department Table
Id Name EMPID
1 SQL. 2
2. PHP. 4
3. JAVA. 1
4 PEARL. 5
QUESTION
i want those records of teacher which are not link with any Department.
you can use following statement using left join then filter Teacher that not matched
SELECT t.*
FROM Teacher t
left join Department d on d.EMPID = t.Id
where d.id is null
SELECT * FROM teachers WHERE
id NOT IN (SELECT DISTINCT EMPID FROM departments) ;
Hope this helps.!!
you can do it by inner query..
select * from teacher where id not in (select empid from department);

SQL: Find common rows in different record

I have 3 tables:
Teacher Table (t_id, email, ...)
Student Table (s_id, email, ...)
Teaching Table (t_id, s_id, class_time, ...)
I have a task which is, given two t_id, find the common students that these 2 teachers have taught.
Is it possible to accomplish this in strictly SQL? If not I might try to retrieve out the student records individually based on different teacher, and do a search to see which students they have in common. This seems a bit overkill for something that seems possible to write a SQL query for.
You can self join to get students for both teachers.
DECLARE #TeacherID1 INT = 1
DECLARE #TeacherID2 INT = 2
SELECT
StudentID = T1.s_id,
Teacher1 = T1.t_id,
Teacher1ClassTime = T1.class_time ,
Teacher2 = T2.t_id,
Teacher2ClassTime = T2.class_time
FROM
TeachingTable T1
INNER JOIN TeachingTable T2 ON T2.s_id=T1._sid AND T2.t_id=#TeacherID2
WHERE
T1.t_id = #TeacherID1
ORDER BY
T1.ClassTime
select s_id
from student a
inner join teaching b on a.s_id = b.s_id
where t_id = 'First give t_id'
INTERSECT
select s_id
from student a
inner join teaching b on a.s_id = b.s_id
where t_id = 'Second give t_id'
This work with MS DB, but probably not with others.
select s_id
from student a
inner join teaching b on a.s_id = b.s_id
where b.t_id = 'First give t_id'
and s_id in (
select s_id
from student c
inner join teaching d on c.s_id = d.s_id
where d.t_id = 'Second give t_id'
)
the second one should work with any DB.

Oracle Statement does not count correctly

I've got a SQL-statement with a - for me not explainable - strange behaviour.
Perhaps you could find what's wrong:
When I use the statement
select count(*) from department
I got 2755 results
Using the following statement
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.buildingid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.buildingid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
I got 2755 results too.
But when I want to combine the two statements with a left join:
select count(*) from department
left join
(
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.buildingid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.buildingid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
) postadress
on
department.buildingid = postadress.buildingid;
I got 3648513 results.
My expectation was, that I get only 2755 results.
Where's the mistake?
Thanks for help!
I assume that buildingid is not unique (for my reasoning to hold true, it can't be unique)
Imagine following simple tables
TableA
create TableA (name VARCHAR(32));
insert into TableA values ('Lieven');
insert into TableA values ('Lieven');
TableB
create TableB (name VARCHAR(32));
insert into TableB values ('Lieven');
insert into TableB values ('Lieven');
insert into TableB values ('AnyOtherValue');
Select statement
select * from TableA a left outer join TableB b on a.name = b.name
As each record of TableA is matched with each record of TableB where the name is equal, this will result in 4 records (the AnyOtherValue is dissmissed as it doesn't match)
The first record of TableA is returned with two of three records of `TableB'
The second record of TableA is returned with two of three records of `TableB'
The query
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.buildingid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.buildingid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
will return one row per department that has usepostaladresssupporter as either 0 or 1 (note that records with other values will not be included, this may or may not be a problem depending on the constrainst of this column).
The unique key of this query results is probably something like departmentid (you will need to include that column in your select criteria).
So the correct query should look something like this:
select * from department
left join
(
select
building1.street, building1.streetno, building1.plz, building1.city, dept1.departmentid
from
department dept1
left join
supporter sup
on
dept.supporterid = sup.id
left join
building building1
on
sup.buildingid = building1.ibuildingid
where
dept.usepostaladresssupporter = 1
union all
select
building2.street, building2.streetno, building2.plz, building2.city, dept2.departmentid
from
building building2
right join
tueks_department dept2
on
dept2.buildingid = building2.ibuildingid
where
dept2.usepostaladresssupporter = 0
) postadress
on
department.departmentid = postadress.departmentid;
Your query will go wrong on data something like this:
Departmentid BuildingId Name
1 1 Dept1
2 2 Dept2
3 2 Dept3
The multiplying effect is not quite equal to deptcount * deptcount, but rather it is buildingcount * buildingcount + deptcount - buildingcount

multiple conditions in same column with relation

Here is the case:
There is a user table
id email orders_counter
=================================
1 a#a.com 5
2 b#b.com 3
3 c#c.com 0
And a user data table for user's other data
id user_id title value
=======================================
1 1 Name Peter Johnson
2 1 Tel 31546988
3 2 Name Alan Johnson
4 2 Tel 56984887
If I want to fetch all user that
1, orders_counter greater then 3
2, Name contain 'Johnson'
3, Tel contain '88'
AT THE SAME TIME
What is my sql, and if I want to do it rubyonrails way
what is the ActiveRecord code
I know I can it one by one and then join all of them together, but it waste too much resource while conditions build up
Select * From `user` u
inner join `userdata` d on d.user_id=u.id and d.title='Name' and d.value like '%Johnson%'
inner join `userdata` c on c.user_id=u.id and c.title='Tel' and c.value like '%88%'
where orders_counter > 3
the way that you've got your user data table structured, you'll almost always have to join on that table several times in order to "pivot" those values into columns. I'd recommend just creating a table that has name and tel as columns. then the query becomes a lot more simple
select * from `user` u
inner join `user_data` d on d.Tel like '%88%' and d.Name like '%johnson%'
where u.orders_counter > 3
try this one up,
SELECT a.*, b.*
FROM user a
INNER JOIN data b
ON a.id = b.user_ID
WHERE a.orders_counter > 3 AND
(b.title = 'NAME' AND b.value like '%johnson%') AND
(b.title = 'TEL' AND b.tel like '%88%')
try this:
select *
from user U join user_data D
on U.id=D.user_id
where U.orders_counter>3
and D.title='Name' and value like '%Johnson%'
and D.title='Tel' and value like '%88%'