I have 2 queries in big query where i want to join 2 tables in some condition.
First query
Second query is same but im using JOIN instead of LEFT JOIN.
Can anyone explain me why LEFT JOIN with WHERE condition returns diffrent results count then INNER JOIN?
why LEFT JOIN with WHERE condition returns diffrent results count then INNER JOIN?
They are considering different starting sets to work with. Here are some nice illustrations on difference between joins:
https://www.diffen.com/difference/Inner_Join_vs_Outer_Join
https://www.codeproject.com/Articles/33052/Visual-Representation-of-SQL-Joins
Relevant images from referenced urls are here:
note that OUTER is optional so left outer join is equal to left join
Related
I have multiple SQL queries that look similar where one uses JOIN and another LEFT OUTER JOIN. I played around with SQL and found that it the same results are returned. The codebase uses JOIN and LEFT OUTER JOIN interchangeably. While LEFT JOIN seems to be interchangeable with LEFT OUTER JOIN, I cannot I cannot seem to find any information about only JOIN. Is this good practice?
Ex Query1 using JOIN
SQL
SELECT
id,
name
FROM
u_users customers
JOIN
t_orders orders
ON orders.status=='PAYMENT PENDING'
Ex. Query2 using LEFT OUTER JOIN
SQL
SELECT
id,
name
FROM
u_users customers
LEFT OUTER JOIN
t_orders orders
ON orders.status=='PAYMENT PENDING'
As previously noted above:
JOIN is synonym of INNER JOIN. It's definitively different from all
types of OUTER JOIN
So the question is "When should I use an outer join?"
Here's a good article, with several great diagrams:
https://www.sqlshack.com/sql-outer-join-overview-and-examples/
The short answer your your question is:
Prefer JOIN (aka "INNER JOIN") to link two related tables. In practice, you'll use INNER JOIN most of the time.
INNER JOIN is the intersection of the two tables. It's represented by the "green" section in the middle of the Venn diagram above.
Use an "Outer Join" when you want the left, right or both outer regions.
In your example, the result set happens to be the same: the two expressions happen to be equivalent.
ALSO: be sure to familiarize yourself with "Show Plan" (or equivalent) for your RDBMS: https://www.sqlshack.com/execution-plans-in-sql-server/
'Hope that helps...
First the theory:
A join is a subset of the left join (all other things equal). Under some circumstances they are identical
The difference is that the left join will include all the tuples in the left hand side relation (even if they don't match the join predicate), while the join will only include the tuples of the left hand side that match the predicate.
For instance assume we have to relations R and S.
Say we have to do R JOIN S (and R LEFT JOIN S) on some predicate p
J = R JOIN S on (p)
Now, identify the tuples of R that are not in J.
Finally, add those tuples to J (padding any attribute in J not in R with null)
This result is the left join:
R LEFT JOIN S (p)
So when all the tuples of the left hand side of the relation are in the JOIN, this result will be identical to the Left Join.
back to you problem:
Your JOIN is very likely to include all the tuples from Users. So the query is the same if you use JOIN or LEFT JOIN.
The two are exactly equivalent, because the WHERE clause turns the LEFT JOIN into an INNER JOIN.
When filtering on all but the first table in a LEFT JOIN, the condition should usually be in the ON clause. Presumably, you also have a valid join condition, connecting the two tables:
SELEC id, name
FROM u_users u LEFT JOIN
t_orders o
ON o.user_id = u.user_id AND o.status = 'PAYMENT PENDING';
This version differs from the INNER JOIN version, because this version returns all users even those with no pending payments.
Both are the same, there is no difference here.
You need to use the ON clause when using Join. It can match any data between two tables when you don't use the ON clause.
This can cause performance issue as well as map unwanted data.
If you want to see the differences you can use "execution plans".
for example, I used the Microsoft AdventureWorks database for the example.
LEFT OUTER JOIN :
LEFT JOIN :
If you use the ON clause as you wrote, there is a possibility of looping.
Example "execution plans" is below.
You can access the correct mapping and data using the ON clause complement.
select
id,
name
from
u_users customers
left outer join
t_orders orders on customers.id = orders.userid
where orders.status=='payment pending'
I am trying to have my query pull data to include all dates from my one tbl_actual even though there is no data for certain dates in my tbl_planned.
But when using my Inner Join and my Left Join together, it is saying that the Left Join is not supported.
I have tried to use two inner joins instead of a left join, but that still only pulls dates from the tbl_planned query, I need all dates from tbl_actual too
SELECT cal.Day, planned.LocalDay, actual.LocDay, actual.Over30Minutes,
actual.Over30MinutesHours, actual.NumOfUses, actual.TotalDurationTaken,
planned.Campaign, planned.Supervisor, planned.DurationScheduled,
actual.PersonID, planned.PersonID
FROM (tbl_actual AS actual INNER JOIN tbl_planned AS planned ON
(planned.PersonID = actual.PersonID)) Left Join tbl_actual ON actual.LocDay
= planned.LocalDay
I am trying to have my query pull data to include all dates from my one tbl_actual even though there is no data for certain dates in my tbl_planned.
In SQL, this can be expressed as tbl_actual LEFT JOIN tbl_planned, followed by the joining conditions (date and person). Records in tbl_actual with no match in tbl_planned will still be included in the output, with all columns related to tbl_planned showing NULL.
I guess that your query could just be simplified as follows :
SELECT
-- cal.Day,
planned.LocalDay,
actual.LocDay,
actual.Over30Minutes,
actual.Over30MinutesHours,
actual.NumOfUses,
actual.TotalDurationTaken,
planned.Campaign,
planned.Supervisor,
planned.DurationScheduled,
actual.PersonID,
planned.PersonID
FROM
bl_actual AS actual
LEFT JOIN tbl_planned
ON planned.PersonID = actual.PersonID
AND actual.LocDay = planned.LocalDay
PS : what is table alias cal, as shown in cal.Day, the first column of your resultset ? This alias is not declared anywhere in the query, I commented out the column.
I think you want to refer tbl_actual only once:
FROM tbl_actual AS actual INNER JOIN
tbl_planned AS planned
ON planned.PersonID = actual.PersonID AND
actual.LocDay = planned.LocalDay
I have a query that joins many related tables together and as a result, it returns duplicate rows for those items with multiple data against them.
I've searched for answers to this on stack and via google but all the results show things like using 'DISTINCT' or creating a subquery. I can't get any solution to work and I think the confusion I face is because of the many joins I have.
Can someone guide me on how to stop my results shows duplicates? Here is my query so far.
SELECT dbo.Vessel.VesselId,
dbo.Vessel.Name,
dbo.Capacity.DeckAreaM2,
dbo.Vessel.DPClassId,
dbo.Subsea.Accomodation,
dbo.Subsea.RovHangar,
dbo.Crane.SWL
FROM dbo.Vessel INNER JOIN
dbo.Capacity ON dbo.Vessel.VesselId = dbo.Capacity.VesselId LEFT OUTER JOIN
dbo.DeckEquipment ON dbo.Vessel.VesselId = dbo.DeckEquipment.VesselId LEFT OUTER JOIN
dbo.Crane ON dbo.DeckEquipment.DeckEquipmentId = dbo.Crane.DeckEquipmentId LEFT OUTER JOIN
dbo.Subsea ON dbo.Vessel.VesselId = dbo.Subsea.VesselId
First of all, does your query even work? There's no such thing as LEFT INNER JOIN ; you may have an INNER JOIN, a LEFT JOIN, or a LEFT OUTER JOIN, with the latter two being the same.
Second, I can understand your non-willingness to make an additional subquery, but why are you against the DISTINCT operator?
Third, if you use a GROUP BY and put there ONLY the fields you want, it will be equivelant to a DISTINCT operator and will return the results you need.
Last but not least, you need to show us what you are getting and what you want instead, if we are to be able to help you more.
I have a select SQL query which is really big and it should be pulling in about 5000 records. But when I use the JOIN It cuts the number of records to say 1000 because it only shows records where a value exists on the joined value, how would I go about pulling all records no matter whether the Join finds that a value exists or NOT?
Left outer join : MSDN Outer Joins
Instead of performing an inner join, perform a left outer join
What is the difference between an inner join and outer join? What's the precise meaning of these two kinds of joins?
Check out Jeff Atwood's excellent:
A Visual Explanation of SQL Joins
Marc
Wikipedia has a nice long article on the topic [here](http://en.wikipedia.org/wiki/Join_(SQL))
But basically :
Inner joins return results where there are rows that satisfy the where clause in ALL tables
Outer joins return results where there are rows that satisfy the where clause in at least one of the tables
You use INNER JOIN to return all rows from both tables where there is a match. ie. in the resulting table all the rows and columns will have values.
In OUTER JOIN the resulting table may have empty columns. Outer join may be either LEFT or RIGHT
LEFT OUTER JOIN returns all the rows from the first table, even if there are no matches in the second table.
RIGHT OUTER JOIN returns all the rows from the second table, even if there are no matches in the first table.
INNER JOIN returns rows that exist in both tables
OUTER JOIN returns all rows that exist in either table
Inner join only returns a joined row if the record appears in both table.
Outer join depending on direction will show all records from one table, joined to the data from them joined table where a corresponding row exists
Using mathematical Set,
Inner Join is A ^ B;
Outer Join is A - B.
So it is (+) is your A side in the query.
Assume an example schema with customers and order:
INNER JOIN: Retrieves customers with orders only.
LEFT OUTER JOIN: Retrieves all customers with or without orders.
RIGHT OUTER JOIN: Retrieves all orders with or without matching customer records.
For a slightly more detailed infos, see Inner and Outer Join SQL Statements