How to combine Inner Join and Left Join in SQL Query statement? - sql

Given this Diagram:
What is the right way to use join that will includes all necessary fields from different tables (person name, employee number, status of contracts, job name, department name, pcn/item name, country, and religion)? BUT I want also to include all persons that choose not to put either thier country or religion. I have this query:
SELECT persons.fullname, religions.religion_name, countries.country_name
FROM countries INNER JOIN (religions INNER JOIN (persons INNER JOIN
((jobs INNER JOIN (departments INNER JOIN pcns ON departments.ID = pcns.department_id) ON jobs.ID = pcns.job_id)
INNER JOIN (employees INNER JOIN contracts ON employees.ID = contracts.employee_id) ON pcns.ID = contracts.pcn_id)
ON persons.ID = employees.person_id) ON religions.ID = persons.religion) ON countries.ID = persons.country_id;
I used LEFT JOIN but I got an error. Right now, I only query all my tables except for countries and religions then I made a function that whenever a user clicks particular person this function will return its religion and/or country. I am just curious how to achieve it in a SELECT query.

Related

Joining two indirectly related tables without including columns from tables in between

Based on the following ERD, I'm trying to write a query that displays reservations made directly by customers and include reservation id, reservation date, customer id, customer first name, tour trip id, tour category name, tour trip date
I've been able to include everything in my query except for the tour category name because the TOUR_SITES table is in the way. Is there a way I can join the category name from the TOUR_PACKAGE table without adding any extra columns?
SELECT r.RESERVATION_ID, r.RESERVATION_DATE,
c.CUSTOMER_ID, c.FIRST_NAME,t.TRIP_ID, o.TRIP_DATE/*, P.CATEGORY_NAME*/
FROM CUSTOMER c
INNER JOIN RESERVATION r
ON
r.CUSTOMER_ID=c.CUSTOMER_ID
INNER JOIN TOURTRIP_RESERVATION t
ON
r.RESERVATION_ID=t.RESERVATION_ID
INNER JOIN TOUR_TRIP O
ON
t.TRIP_ID=o.TRIP_ID
WHERE AGENT_ID IS NULL;
Is there a way I can join the category name from the TOUR_PACKAGE table without adding any extra columns?
Sure; just join all tables you need. You don't have to add additional columns (the ones you don't need) into the select column list, but you do have to use the tour_sites table anyway.
Something like this:
select r.reservation_id, r.reservation_date,
c.customer_id, c.first_name,t.trip_id, o.trip_date,
p.category_name
from customer c inner join reservation r on r.customer_id=c.customer_id
inner join tourtrip_reservation t on r.reservation_id=t.reservation_id
inner join tour_trip o on t.trip_id=o.trip_id
--
join tour_sites s on s.tour_siteid = o.tour_siteid --> add
join tour_package p on p.category_id = s.category_id --> this
where agent_id is null;
You need to first join tour_sites with tour_trip on TOUR_SITEID and then join tour_package with tour_sites on category_id to get the tour category_name. You can join left join on tour_sites in case there are no tour sites assigned for a tour trip like a newly added tour_trip.
SELECT r.RESERVATION_ID, r.RESERVATION_DATE, c.CUSTOMER_ID, c.FIRST_NAME,t.TRIP_ID, o.TRIP_DATE,TP.CATEGORY_NAME
FROM CUSTOMER c
INNER JOIN RESERVATION r ON r.CUSTOMER_ID=c.CUSTOMER_ID
INNER JOIN TOURTRIP_RESERVATION t ON r.RESERVATION_ID=t.RESERVATION_ID
INNER JOIN TOUR_TRIP O ON t.TRIP_ID=o.TRIP_ID
LEFT JOIN TOUR_SITES TS ON TS.TOUR_SITEID = O.TOUR_SITEID
INNER JOIN TOUR_PACKAGE TP ON TP.CATEGORY_ID = TS.CATEGORY_ID
WHERE AGENT_ID IS NULL;

Nested 'Where'?

I have a table named Actor, with only a column for City (CityId). I want to return the number of actors in a particular State (StateId). The catch however is that I have separate tables for City, County, and finally State (City has CountyId, County has StateId). How do I this in a T-SQL query?
I have a solution that involves nested Select statements, something like:
SELECT COUNT(1)
FROM Actor a
WHERE a.CityId IN
(SELECT CityId FROM City WHERE CountyId IN...)
...but is there a more efficient way to do this? Thanks
You can use this query to get your output
----------------------------------------------------------
SELECT COUNT(ActorId)
FROM Actor a
INNER JOIN City c ON a.cityId = c.cityId
INNER JOIN Country con ON c.countryId = con.countryId
INNER JOIN STATE s ON con.stateId = s.stateId
GROUP BY s.stateId
Use JOINS to query your data.
I am using INNER JOIN here.
Assuming that you have CountryId in your City Table, You can do it following way.
In case you don't have countryId in your City Table you have to apply one more INNER JOIN on State Table.
SELECT COUNT(1) FROM Actor a INNER JOIN
City b ON a.CityId = b.CityId
WHERE b.CountryId IN (...)
You can easily put the JOINS across different table that you have and then use the Group By clause to find out the total number of actors from specific state.
I have used the column name on the basis of my wild guess, you can change them with the original name that you have in your database.
SELECT StateId,
Count(ActorId) AS Total
FROM ACTOR
INNER JOIN City ON Actor.CityId = City.CityId
INNER JOIN County ON County.CountyId = City.CountyId
INNER JOIN State ON State.StateId = County.StateId
GROUP BY State.StateId
Assuming the relation names, you can do something like this with joins:
select s.ID, s.Name, count(*)
from Actors a
inner join Cities c on c.ID = a.CityID
inner join County cn on cn.ID = c.CountyID
inner join State s on s.ID = cn.StateID
group by s.ID, s.Name
If you only need the StateId you don't even need to join with states, this will do:
select cn.StateID, count(*)
from Actors a
inner join Cities c on c.ID = a.CityID
inner join County cn on cn.ID = c.CountyID
group by cn.StateID

Outer Join or NOT IN

Need a little help solving problem. Apologies if this is vague which is why I need help. Show The title ID, title, publisher id, publisher name, and terms for all books that have never been sold. This means that there are no records in the Sales Table. Use OUTER JOIN or NOT IN against SALES table. In this case, the terms are referring to the items on the titles table involving money. ( Price, advance, royalty ).
I've come up with the following code and there are no records returned. I've looked at the tables and no records should be returned. Not sure my code is correct based on using the OuterJoin or NOT IN. Thanks!
SELECT titles.title_id,
titles.title,
publishers.pub_id,
sales.payterms,
titles.price,
titles.advance,
titles.royalty
FROM publishers
INNER JOIN titles
ON publishers.pub_id = titles.pub_id
INNER JOIN sales
ON titles.title_id = sales.title_id
WHERE (sales.qty = 0)
I believe all you need it to change the INNER JOIN to a LEFT JOIN for your sales table. Then check for NULL on any of the columns from the sales table.
SELECT titles.title_id, titles.title, publishers.pub_id, sales.payterms,
titles.price, titles.advance, titles.royalty
FROM publishers INNER JOIN
titles ON publishers.pub_id = titles.pub_id LEFT JOIN
sales ON titles.title_id = sales.title_id
WHERE sales.qty IS NULL
Well, you are using INNER JOIN so it will only return records that match the join condition which is not what you want. You should use LEFT OUTER JOIN (or LEFT JOIN) and check that the sales side is null (meaning there's no record matching).
SELECT titles.title_id, titles.title, publishers.pub_id, sales.payterms,
titles.price, titles.advance, titles.royalty
FROM publishers INNER JOIN
titles ON publishers.pub_id = titles.pub_id LEFT OUTER JOIN
sales ON titles.title_id = sales.title_id
WHERE sales.title_id IS NULL
IS NULL Means that a data value does not exist in the database. And just change your INNER JOIN TO LEFT JOIN.
use this..
SELECT titles.title_id,
titles.title,
publishers.pub_id,
sales.payterms,
titles.price,
titles.advance,
titles.royalty
FROM publishers
INNER JOIN titles
ON publishers.pub_id = titles.pub_id
LEFT JOIN sales
ON titles.title_id = sales.title_id
WHERE (sales.qty IS NULL)

LEFT OUTER JOIN with INNER JOIN

I have a table of students.
and a table of teachers.
SOME of the students (not all) will have a teacher assigned to them.
this is controlled in a 3rd table, matching those students with their teachers, via the studentID and teacherID
what i need the SQL to do, is to LEFT OUTER JOIN onto the 3rd table, which is then INNER JOINED onto the teacher's table (because not all students will appear in the 3rd table, but any teacher that appears in the 3rd table WILL appear in the teachers table).
i am looking to get a result of all student names, and teacher's name, where they are assigned (and null if not).
what i have so far looks like this, and it basically operates as a full INNER JOIN, and does not give me students who do not have teachers assigned:
SELECT firstname, teacherlastName
FROM tblstudents
left outer join [tblStudentRakazot]
ON tblstudents.studentid = [tblStudentRakazot].studentID
INNER JOIN tblteachers
ON [tblStudentRakazot].teacherid = tblteachers.teacherID
can someone pls give me a pointer here? i tried with placing brackets, but that didn't see, to help.
thanks!
You don't use an INNER JOIN but only another LEFT JOIN.
Think of tblStudents as your base. You want to get all of them, not filter anything out, and only attach optional info.
With the first left join, you attach a first info
Student -> TeacherAssignment
The TeacherAssignment can be null or not null.
Now you only attach another info - the teacher's full name pulled from tblTeachers.
Student -> TeacherAssignnent -> TeacherName
Do this with another LEFT JOIN. That attaches the info, where possible, i.e. where TeacherAssignment is not null.
This ignores rows where TeacherAssignment is null anyway.
SELECT firstname, teacherlastName
FROM tblstudents
left outer join
( select * from
[tblStudentRakazot] A INNER JOIN tblteachers B
ON A.teacherid = B.teacherID)AS C
ON tblstudents.studentid = C.studentID
You could move your INNER JOIN to a subquery
SELECT firstname, teacherlastName
FROM tblstudents
LEFT OUTER JOIN
( SELECT [tblStudentRakazot].studentID, tblTeachers.teacherlastName
FROM [tblStudentRakazot]
INNER JOIN tblteachers
ON [tblStudentRakazot].teacherid = tblteachers.teacherID
) teachers
ON tblstudents.studentid = teachers.studentID
Another option is to use a more complicated where clause.
SELECT firstname, teacherlastName
FROM tblstudents
LEFT JOIN [tblStudentRakazot]
ON tblstudents.studentid = [tblStudentRakazot].studentID
LEFT JOIN tblteachers
ON [tblStudentRakazot].teacherid = tblteachers.teacherID
WHERE [tblStudentRakazot] IS NULL
OR tblteachers.teacherID IS NOT NULL
However, SQL Server is pretty good at propogating predicates out of subqueries where it needs to, so I would favour the first approach for both readabilty and efficiency.
EDIT
I did not read the question properly, I thought you did not want records where the teacherID in tblStudentRakazot was NULL. If this is not an issue then you can simply use two LEFT JOINS, without the where clause as above:
SELECT firstname, teacherlastName
FROM tblstudents
LEFT JOIN [tblStudentRakazot]
ON tblstudents.studentid = [tblStudentRakazot].studentID
LEFT JOIN tblteachers
ON [tblStudentRakazot].teacherid = tblteachers.teacherID
SELECT b.student_firstname, teacherlastName
FROM thirdtable a
left join studenttbl b on a.studentid = b.studentid
left join teachertbl b on a.teacherid = b.teacherid
You can always use outer join if you are certain data in teacher table is unique. it will give same result as inner join.
You may not use a subquery as in #GarethD sample.
SELECT firstname, teacherlastName
FROM tblstudents
LEFT OUTER JOIN [tblStudentRakazot]
INNER JOIN tblteachers
ON [tblStudentRakazot].teacherid = tblteachers.teacherID
ON tblstudents.studentid = [tblStudentRakazot].studentID
But when looking more deeply execution plans of this query and query with subquery will likely be equivalent.

Two Inner Joins MYSQL

How would I preform two inner joins in one query?
Ie: three tables
Invoice
Address
Client
Invoice has a column which references an id in clients. It also has a column which references an address. I need to get both the clients name from the matched table and the address from the matched table. How would I INNER JOIN both tables?
I'll add a few details...
invoice has rows address(references address id), client(references client id), id and notes
client has rows first_name, last_name
address has rows street_name and city
I need to pull up
You can have as many JOIN clauses as you need in the query. Each has an ON clause where you specify the related columns between the joined tables.
SELECT
columns
FROM
invoice
INNER JOIN
address
ON
join_condition
INNER JOIN
client
ON
join_condition
Something like:
SELECT
c.*, i.*, a.*
FROM
invoices i
INNER JOIN
client c
ON
i.clientid = c.clientid
INNER JOIN
address a
ON
a.clientid = c.clientid
WHERE
i.id = 21
Don't forget you only select the fields you require, not * (all).
A sample e.g. based on learning from #Dan Grossman above:
SELECT FILM.TITLE, ACTOR.FIRST_NAME, ACTOR.LAST_NAME FROM ACTOR
INNER JOIN FILM_ACTOR
ON ACTOR.ACTOR_ID = FILM_ACTOR.ACTOR_ID
INNER JOIN FILM
ON FILM_ACTOR.FILM_ID = FILM.FILM_ID
WHERE ACTOR.FIRST_NAME = 'Nick' AND ACTOR.LAST_NAME = 'Wahlberg'