Find left table and right table when we join more than 2 tables? - sql

Suppose I have three tables here one of them is a Country table second one is a city table and the third one is a customer table, and I am writing a query here like this
SELECT country.country_name_eng, city.city_name, customer.customer_name
FROM Country
LEFT JOIN city ON city.country_id = country.id
LEFT JOIN customer ON customer.city_id = city.id
I want to know here who is the left table of the customer table and who is the left table of the city table as well as who is the right table of the country table and who is the right table of the customer table

'Left' is always the table at the left of the JOIN keyword, no matter if left, right, inner or full outer join, analogously 'right'.
Left and right joins, though, have different semantics:
With a normal (inner) join a data row is only added if there's a matching entry in both tables, e.g. if you JOIN ON l.id = r.id then if l contains an id with value 7 a row for is only added if there's a matching id with value 7 in r as well (and vice versa).
A left (outer) join instead adds a row for id 7 in l even if there's no matching id in r – then the corresponding columns for table r are filled with nulls.
Analogously a right (outer) join, all entries of r are added with nulls for l's columns if no matching entry found.
A full outer join is a combination of left and right outer join, any entry of l and r is used with nulls on either side for the counter part if none exists.
In your concrete query you'd list all countries even if there don't exist any cities – and if they do exist, for each country all of them even if there don't exist any customers there. In the latter case the columns for the customer are all filled with null values, and if no city exists either, additionally all city columns.

Related

Does order matter in theta join

I got 3 relations
customer (customer_name, city)
loan (loan_number, branch_name, amount)
borrower (customer_name, loan_number)
Find customer name, city and their loan amounts.
First query:
SELECT c.customer_name, c.city, l.amount
FROM borrower b
JOIN loan l USING (loan_number)
JOIN customer c USING (customer_name)
Second query:
SELECT c.customer_name, c.city, l.amount
FROM customer c
JOIN borrower b USING (customer_name)
JOIN loan l USING (loan_number)
Will the two queries produce same result?
In inner joins (as opposed to outer joins), the order of tables does not matter.
Short Answer: No. The order doesn't matter for INNER JOIN (and hence for theta join).
Long Answer:
INNER JOIN (or simply JOIN) between two or more tables gives you the intersection of the tables. Think of tables as sets and intersection of the tables is the common area of the sets where there in an overlap of data. No matter where you place the sets, what's common between Set A, Set B and Set C (table A, table B & table C), won't change. Hence, order of tables doesn't matter for INNER JOIN.
When you do LEFT OUTER JOIN between two tables (two sets), you are not just taking the intersection of the two sets. You are actually taking the entire of the set (table) you placed on the left hand side. Similarly, for RIGHT OUTER JOIN, you are taking the entire of set (table) you placed on the right hand side. Hence, for LEFT and RIGHT OUTER JOIN, order of tables does matter.
For FULL OUTER JOIN, you are essentially taking not just the intersection, not just the table on the left or right, but the whole of two tables (or sets). Hence, order doesn't matter again for FULL OUTER JOIN.

JOIN Tables with all specified fields matching

I have two tables. I'm selecting all the values in the first table and trying to get the associated rows in the second table which match BOTH of the specified fields.
So in this example, I want only the rows in the CarsTable and the associated columns in the TrucksTable in which BOTH the Tires and Windows values match (if just one value matches, I don't want it). I'm not even certain a join is the correct operation. Any ideas?
SELECT * FROM CarsTable, TrucksTable
LEFT JOIN TrucksTable t1
ON
t1.Tires = Cars.Tires
LEFT JOIN Trucks t2
ON
t2.Windows = Cars.Windows
You need to do some research on joins...your from clause is all over the place. Carstable,truckstable as you have here is a cross join..and I don't understand what the left joins you are doing are. I think you only have two tables:
SELECT c.*, t.* FROM CarsTable c
inner join TrucksTable t
on t.tires = c.tires and t.windows = c.windows
inner join will function as a filter...if the record in carstable finds no matches in the truckstable by the keys listed, it won't appear. If you want all cartable rows even those that find no match, use left join (in this case, t.* will be null)

When would you INNER JOIN a LEFT JOINed table /

I came across below code today.
SELECT StaffGroup.*
FROM StaffGroup
LEFT OUTER JOIN StaffByGroup
ON StaffByGroup.StaffGroupId = StaffGroup.StaffGroupId
INNER JOIN StaffMember
ON StaffMember.StaffMemberId = StaffByGroup.StaffMemberId
WHERE StaffByGroup.StaffGroupId IS NULL
The main table StaffGroup is being LEFT JOINed with StaffByGroup table and then StaffByGroup table is being INNER JOINed with StaffMember table.
I thought the INNER JOIN is trying to filter out the records which exist in StaffGroup and StaffByGroup but do not exist in StaffMember.
But this is not how it is working. The query does not return any records.
Am I missing something in understanding the logic of the query ? Have you ever used INNER JOIN with a table which has been used with LEFT JOIN in earlier part of the query ?
Actually you are missing one concept:
The main table StaffGroup is being LEFT Joined with StaffByGroup table and then this creates a virtual table say VT1 with all records from StaffGroup and matching records from StaffByGroup based on your match/filter condition in ON predicate.Then not StaffByGroup table but this VT1 is being INNER Joined with StaffMember table based on match/filter condition in ON predicate.
So basically the inner join is trying to filter out those records from StaffGroup and hence StaffByGroup which do not have a StaffMemberId.
Adding your where condition adds a final filter like from the final virtual table created by all the above joins remove all such records which don't have a StaffGroupId which in turn might be removing all rows collected in VT1 as all of them will be having some value for StaffGroupId.
To get all records from StaffGroup which have no StaffGroupId along with details from StaffMember for all such records you can add condition in ON predicate as:
SELECT StaffGroup.*
FROM StaffGroup
LEFT OUTER JOIN StaffByGroup
ON StaffByGroup.StaffGroupId = StaffGroup.StaffGroupId and StaffByGroup.StaffGroupId IS NULL
INNER JOIN StaffMember
ON StaffMember.StaffMemberId = StaffByGroup.StaffMemberId
This query looks fundamentally flawed - I guess what was originally intended is
SELECT StaffGroup.*
FROM StaffGroup
LEFT OUTER JOIN
(SELECT * FROM StaffByGroup
INNER JOIN StaffMember
ON StaffMember.StaffMemberId = StaffByGroup.StaffMemberId) StaffByGroup
ON StaffByGroup.StaffGroupId = StaffGroup.StaffGroupId
WHERE StaffByGroup.StaffGroupId IS NULL
which returns all groups from StaffGroup that dont' have existing staffmembers assigned to them (the INNER JOIN with StaffMember filters out those rows from StaffByGroup that don't have a matching row in StaffMember - probably because there exists no foreign key between them)
You are getting 0 records because of your where clause
where StaffByGroup.StaffGroupId is null
The left join links all the records from tbl A which are contained in tbl B and since you have specified StaffGROUPID as your key and then looked for Nulls values in your key, its 100% clear that you will end up with no results

I want to retrieve data from 4 tables in SQL Server

I want to retrieve data from 4 tables. Patient table has id as PK which is the foreign key in other three tables ett, phar and ssc. Where a patient lie in only one category. i.e patient id pt1 exists in either of the 3 tables. now I want to retrieve patient info along with its associated category.
My query is:
SELECT *
FROM Patient p
INNER JOIN ETT t
ON p.Patient_ID = t.Patient_ID || INNER JOIN Pharmacological ph
ON p.Patient_ID = ph.Patient_ID
I used OR clause because I want only 1 inner join executing at one time. but its not giving me results, any suggestions??
....Patient table has ID as PK which is the foreign key in other three
tables name: ett, phar and ssc where a patient lie in only one
category. Example, patient id pt1 exists in either of the 3 tables.
Based on your statement, you can join all the tables in table Patient using LEFT JOIN since a record can only exist on one table. The query below uses COALESCE which returns the first non-null value with int the list.
The only thing you need is to manually specify the column names that you want to be shown on the list as shown below.
SELECT a.*,
COALESCE(t.colA, p.ColA, s.ColA) ColA,
COALESCE(t.colB, p.ColB, s.ColB) ColB,
COALESCE(t.colN, p.ColN, s.ColN) ColN
FROM Patient a
LEFT JOIN ETT t
ON a.Patient_ID = t.Patient_ID
LEFT JOIN Phar p
ON a.Patient_ID = p.Patient_ID
LEFT JOIN SSC s
ON a.Patient_ID = s.Patient_ID
To further gain more knowledge about joins, kindly visit the link below:
Visual Representation of SQL Joins
For or - do not ise ||, use "or"
You cannot join with or, you need re-format your query.

SQL SELECT foreign key rows that have no rows in child table

I need the following code to still show rows from the AUTHOR table even if they aren't called from any rows in the ALLOCATION table. Currently, the code shows all ALLOCATION rows with the appropriate foreign key data. I need it so that all rows from the AUTHOR table show up, even if they have no corresponding ALLOCATION row.
SELECT authid,sname,fname,B.bid
FROM ALLOCATION A
INNER JOIN BOOK B
ON A.bid = B.bid
INNER JOIN AUTHOR U
ON A.authid = U.authid
ORDER BY authid;
That is, some of the rows in the AUTHOR table are the foreign key of 0 of the rows in the ALLOCATION table. I need them to show up as well in a SELECT. authid, sname and fname are columns of the AUTHOR table.
select authid,
sname,
fname,
B.bid
from AUTHOR U
left outer join ALLOCATION A on A.authid = U.authid
left outer join BOOK B on A.bid = B.bid
order by authid
You want to use something called an outer join.
Instead of INNER, say LEFT OUTER or RIGHT OUTER, depending on the direction.
What this does is if there is no corresponding record in the other table, the columns are filled with null.