How to JOIN several tables? - sql

On MS SQL Server i want to join some tables in one select.
Tables:
Track:
Segment_ID | Track_INFO
Segment_ID:
Segment_ID | Road_ID
Road:
Road_ID | Road_INFO
So i want to select information from Track and Road tables. I know how to join two tables:
SELECT
Segment_ID = T1.Segment_ID,
Track = T1.Track,
--Road_ID = Segment_ID.Road_ID
FROM dbo.Track T1,dbo.Road T2
LEFT JOIN Segment_ID Segment_ID ON Segment_ID.Segment_ID = T1.Segment_ID
--LEFT JOIN Road Road_ID ON Road.Road_ID = Segment_ID.Road_ID
But how to make JOIN in my case?

Try this:
SELECT Track.Track_INFO, Road.Road_INFO
FROM Track
INNER JOIN Segment_ID ON Segment_ID.Segment_ID = Track.Segment_ID
INNER JOIN Road ON Segment_ID.Road_ID = Road.RodaID
And also, maybe you need LEFT join if you have Null marks...

select *
from Track inner join Segment_ID on Track.Segment_ID = Segment_ID.Segment_ID
inner join Road on Segment_ID.Road_ID = Road.Road_ID
also you can change "inner join"s to "left join"s depending on the behaviour you want

Try this:
SELECT t.*, r.*
FROM track t
INNER JOIN segment s ON t.Segment_ID = s.Segment_ID
INNER JOIN road r ON s.Road_ID = s.Road_ID

Try to avoid table joining as below which is obsolete now.
FROM Table1 T1, Table2 T2
WHERE T1.id = T2.id
Better way of joining table is using INNER JOIN (or JOIN), LEFT JOIN, RIGHT JOIN etc depending on your requirement like;
SELECT * --Or you can get required list of columns using table aliases (t,s,r)
FROM dbo.Track t JOIN dbo.Segment_ID s ON t.Segment_ID = s.Segment_ID
JOIN dbo.Road r ON s.Road_ID = r.Road_ID
Here are some good graphical examples about JOINS and what results they bring

Related

Optimising SQL Query with multiple joins, reducing query speed

I'd like some advice on how to optimize the code below. I have attached the relationship of table above, any feedback or direction you could point me to will be appreciated.
The current query seems to be taking quite long to process.
SELECT CUSTINVOICETRANS.INVENTTRANSID, CUSTINVOICETRANS.INVOICEDATE, CUSTINVOICETRANS.INVOICEID, CUSTINVOICETRANS.ITEMID, CUSTINVOICETRANS.LINEAMOUNT, CUSTINVOICETRANS.LINEAMOUNTTAX, CUSTINVOICETRANS.ORIGSALESID, CUSTINVOICETRANS.QTY, CUSTINVOICETRANS.SUMLINEDISC, CUSTINVOICEJOUR.CUSTGROUP, CUSTINVOICEJOUR.INVOICEACCOUNT, CUSTINVOICEJOUR.SALESID, SALESTABLE.VCORDERMODE, SALESTABLE.VCORDERRT, VCSALESTABLEINFO.RCVDATE, VCSALESTABLEINFO.SHPCSTMCD, VCSALESTABLEINFO.VCORIGINALINVOICEDATE, SALESLINE.DATAAREADID, SALESLINE.INVENTTRANSID, VCSALESLINEINFO.RLLINEID
FROM CUSTINVOICETRANS
INNER JOIN CUSTINVOICEJOUR
ON CUSTINVOICETRANS.INVOICEID = CUSTINVOICEJOUR.INVOICEID
AND CUSTINVOICETRANS.INVOICEDATE = CUSTINVOICEJOUR.INVOICEDATE
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN SALESTABLE
ON CUSTINVOICETRANS.ORIGSALESID = SALESTABLE.SALESID
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN VCSALESTABLEINFO
ON CUSTINVOICETRANS.ORIGSALESID = VCSALESTABLEINFO.SALESID
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN SALESLINE
ON CUSTINVOICETRANS.ORIGSALESID = SALESLINE.SALESID
AND CUSTINVOICETRANS.INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
INNER JOIN VCSALESLINEINFO
ON SALESLINE.INVENTTRANSID = VCSALESLINEINFO.INVENTTRANSID```
You can use cte to filter first your customer invoice transactions before joining other tables.
WITH cte as
(
SELECT INVENTTRANSID, INVOICEDATE, INVOICEID
, ITEMID, LINEAMOUNT, LINEAMOUNTTAX
, ORIGSALESID, QTY, SUMLINEDISC
FROM CUSTINVOICETRANS WHERE INVOICEDATE>=DATEADD(DAY,-7,GETDATE())
)
SELECT t1.*, t2.CUSTGROUP, t2.INVOICEACCOUNT, t2.SALESID
, t3.VCORDERMODE, t3.VCORDERRT
, t4.RCVDATE, t4.SHPCSTMCD, t4.VCORIGINALINVOICEDATE
, t5.DATAAREADID, t5.INVENTTRANSID
, t6.RLLINEID
FROM cte t1
INNER JOIN CUSTINVOICEJOUR t2 on t2.INVOICEID = t1.INVOICEID and t1.INVOICEDATE = t2.INVOICEDATE
INNER JOIN SALESTABLE t3 on t3.SALESID = t1.ORIGSALESID
INNER JOIN VCSALESTABLEINFO t4 on t4.SALESID = t1.ORIGSALESID
INNER JOIN SALESLINE t5 on t5.SALESID = t1.ORIGSALESID
INNER JOIN VCSALESLINEINFO t6 on t6.INVENTTRANSID = t5.INVENTTRANSID
Pull the first INNER JOIN outcome to a dataframe / temp table t1.
Join the same with second INNER Join dataset.
pull the data into another temp table / data frame.
Drop the temp table t1 at the end.
Follow the step for for subsequesnt joins.
Regards

SQL SERVER: JOIN 2 already joined sections of tables

I already LEFT JOINed many tables into two sections, but now how do I join these two together?
I am not sure if subquery would work but at least I tried subquery its very confused/
SELECT MoviePerson.PersonId, MoviePerson.PersonFirstName, MoviePerson.PersonLastName, MoviePersonRole.RoleId FROM MoviePerson
LEFT JOIN MoviePersonRole ON MoviePerson.PersonId = MoviePersonRole.PersonId;
select DVD.DVDId, DVD.GenreId, DVD.RatingId, DVD.DVDTitle, DVD.DVDReleasedate, DVD.TheaterReleaseDate, Genre.GenreName, Rating.RatingName,
Rating.RatingDescription
from DVD
LEFT join Genre on DVD.GenreId = Genre.GenreID
LEFT JOIN Rating ON DVD.RatingId = Rating.RatingId
LEFT JOIN MoviePersonRole ON DVD.DVDId =MoviePersonRole.DVDId
;
db<>fiddle
It doesn't look as though you have a column to join on. If you did, you could use the following syntax:
SELECT *
FROM
(
SELECT MoviePerson.PersonId, MoviePerson.PersonFirstName, MoviePerson.PersonLastName, MoviePersonRole.RoleId FROM MoviePerson
LEFT JOIN MoviePersonRole ON MoviePerson.PersonId = MoviePersonRole.PersonId;
) X
INNER JOIN
(
select DVD.DVDId, DVD.GenreId, DVD.RatingId, DVD.DVDTitle, DVD.DVDReleasedate, DVD.TheaterReleaseDate, Genre.GenreName, Rating.RatingName,
Rating.RatingDescription
from DVD
LEFT join Genre on DVD.GenreId = Genre.GenreID
LEFT JOIN Rating ON DVD.RatingId = Rating.RatingId
LEFT JOIN MoviePersonRole ON DVD.DVDId =MoviePersonRole.DVDId
) Y
ON X.column_to_join = y.column_to_join

Unnecessary LEFT JOINs on all Child tables from main LEFT JOIN table required in query for correct result

I am LEFT JOIN-ing the table RECALLS_T with EVENTS_T. Some Recalls do not have any Events, and for those I want a blank row returned.
However, once an entry in EVENTS_T exists, all the following extra tables from EVENTS_T which I also need (ANSWERS_T, ACTIVITY_QUESTIONS_T, ACTIVITES_T) are guaranteed to have entries. For these subsequent tables there is no need to do a LEFT JOIN from their parent, it can be an INNER JOIN just as well.
But if I do the following, the query does not return blank EVENTS_T rows for a RECALLS_T.
SELECT ..
FROM
recalls_t r
LEFT JOIN events_t e ON ( r.id = e.recall_id ) --Only LEFT JOIN this main table
INNER JOIN answers_t ans ON (ans.event_id = e.id)
INNER JOIN activity_questions_t aq ON (ans.activity_question_id = aq.id)
INNER JOIN PUBLIC.activities_t act ON (aq.activity_id = act.id)
Instead, I need to change every subsequent INNER JOIN to a LEFT JOIN as well, in order to get Recalls with blank Events.
SELECT ..
FROM
recalls_t r
LEFT JOIN events_t e ON ( r.id = e.recall_id )
LEFT JOIN answers_t ans ON (ans.event_id = e.id)
LEFT JOIN activity_questions_t aq ON (ans.activity_question_id = aq.id)
LEFT JOIN PUBLIC.activities_t act ON (aq.activity_id = act.id)
I'm just not clear on why I have to do this. The top-level optional join is all I care about, but the downstream joins from EVENTS_T are guaranteed to have data provided the Event exists. Shouldn't the top-level single EVENTS_T join be enough? I'm using Postgres.
The reason you need to do this is because rows preserved by the outer join will have NULL for all columns from events - so inner joining using an equality condition on e.id will remove them from the result again.
you can move the ON clause to the end of the query to give your desired semantics.
The left join is then on the virtual result of inner joining events_t, answers_t, activity_questions_t and activities_t
SELECT ...
FROM recalls_t r
LEFT JOIN events_t e
INNER JOIN answers_t ans
ON ( ans.event_id = e.id )
INNER JOIN activity_questions_t aq
ON ( ans.activity_question_id = aq.id )
INNER JOIN PUBLIC.activities_t act
ON ( aq.activity_id = act.id )
ON ( r.id = e.recall_id )
Or you could consider a RIGHT JOIN here instead
SELECT ...
FROM events_t e
INNER JOIN answers_t ans
ON ( ans.event_id = e.id )
INNER JOIN activity_questions_t aq
ON ( ans.activity_question_id = aq.id )
INNER JOIN PUBLIC.activities_t act
ON ( aq.activity_id = act.id )
RIGHT JOIN recalls_t r
ON ( r.id = e.recall_id )
You have to do this because answers_t`` is joining onevents_s. If thejoinkey (e.recall_id) isNULL`, then there will be no match. And the inner join will not return the row. And so on for the other tables.
You seem to understand the fix. Once you use left join, you need to continue using left join for those tables that are connected to the second table of the left join.

Need to join but on a secondary table

I have this one view all_people_expanded_view that has all the data needed except 1.
The race of client is in race table. But the description is in race_info. I need to join on race on people_id, but really need then to join race on race_info on column race_info_id and then get description. I am stuck on how to make this connection.
select a.full_name, a.dob, a.gender, a.ethnicity, c.race_info_id
from all_people_expanded_view a inner join
race c
on a.people_id = c.people_id
this would be fine but it only has race_info_id and not the description which is in the race_info_id table.
Is this what you're looking for?
select
a.full_name,
a.dob,
a.gender,
a.ethnicity,
c.race_info_id,
ri.description
from
all_people_expanded_view a
inner join
race c
on a.people_id = c.people_id
left join --Maybe an inner join, depending on your data
race_info ri
on ri.race_info_id = c.race_info_id
select
a.full_name, a.dob, a.gender, a.ethnicity, c.race_info_id , ri.description
from
all_people_expanded_view a
inner join race c on a.people_id = c.people_id
inner join race_info ri on ri.race_info_id = c.race_info_id

How to select multiple many to many in relation with a single table

I'm currently working with database, but I've got stuck with a select query.
However, I'm not database expert.
The query should return the data from a table that has two relationships of many to many.
This is my tables Diagram that would shows the concept of my question
The Select Query should View three columns, which are VidTbl.Name, ActorTbl.Name and SubTitelTbl.name.
So, I've read and search in the Internet and I've given tries
First try
SELECT
VidTbl.NAME AS Video_Titel_Name,
ActorTbl.NAME AS Actor_Name
FROM ActorInVid
INNER JOIN VidTbl
ON VidTbl.Id = ActorInVid.FKVidId
INNER JOIN ActorTbl
ON ActorTbl.Id = ActorInVid.FKActorId
UNION all
SELECT
VidTbl.NAME AS Video_Titel_Name,
SubTitelTbl.NAME AS SubTitel_Langu
FROM SubTitelInVid
INNER JOIN VidTbl
ON VidTbl.Id = SubTitelInVid.FKVidId
INNER JOIN SubTitelTbl
ON SubTitelTbl.Id = SubTitelInVid.FKSTId
The Result I've got, it was wrong
Then I tried another way to solve this problem, but again I've got another error
second try
SELECT Temp1.*
From (SELECT VidTbl.Id AS Video_Id,
VidTbl.NAME AS Video_Titel_Name,
ActorTbl.NAME AS Actor_Name
FROM ActorInVid
INNER JOIN VidTbl
ON VidTbl.Id = ActorInVid.FKVidId
INNER JOIN ActorTbl
ON ActorTbl.Id = ActorInVid.FKActorId) AS Temp1
SELECT Temp2.*
FROM (SELECT VidTbl.Id AS Video_Id,
SubTitelTbl.NAME AS SubTitel_Langu
FROM SubTitelInVid
INNER JOIN VidTbl
ON VidTbl.Id = SubTitelInVid.FKVidId
INNER JOIN SubTitelTbl
ON SubTitelTbl.Id = SubTitelInVid.FKSTId) AS Temp2
SELECT *
FROM VidTbl
INNER JOIN Temp1
on Temp1.Video_Id = VidTbl.Id
INNER JOIN Temp2
on Temp2.Video_Id = VidTbl.Id
The error, I've got in the last select that was wrong
Thanks a lot for your help any ways
I wish that my question is clear and useful
Thanks again.
You are close. This should work...
SELECT
VidTbl.Name,
ActorTbl.Name,
SubTitelTbl.name
FROM VidTbl
INNER JOIN ActorInVid ON VidTbl.Id = ActorInVid.FKVidId
INNER JOIN ActorTbl ON ActorTbl.Id = ActorInVid.FKActorId
INNER JOIN SubTitelInVid ON VidTbl.Id = SubTitelInVid.FKVidId
INNER JOIN SubTitelTbl ON SubTitelTbl.Id = SubTitelInVid.FKSTId
SELECT DISTINCT vt.Name, at.Name, st.Name
FROM VidTbl vt
JOIN ActionInVid aiv ON aiv.VidId = vt.Id
JOIN SubtitleInVid siv ON siv.VidId = vt.Id
JOIN ActorTbl at ON at.Id = aiv.ActorId
JOIN SubTitleTbl st ON st.Id = siv.STId