In SQL outer joins, what part of the query puts a table on the "left" or "right"? - sql

I am reading books on outer joins and they reference the "position" of a table in determining whether all of its records will be displayed.
I am confused about how exactly the position (left/right) is determined?
If we consider the standard SQL join
Select * FROM
Table_A left outer join Table_B
on Table_A.ID = Table_B.Product_ID
What part of this query is determining the position of each Table?
Is it the join part:
Table_A left outer join Table_B
Where Table_A is on the "left" because it is left of the join word?
Or is it the "=" part:
on Table_A.ID = Table_B.Product_ID
Where Table_A is on the "left" because it is left of the "=" sign?

This makes the difference, so Table name on left side of LEFT OUTER JOIN is leading one
Table_A left outer join Table_B
As per the MSDN, left outer joins include all of the records from the first (left) of two tables, even if there are no matching values for records in the second (right) table.

It's the relative position of the table name in the SQL.
table1 left join table2
means table 1 is the principle table, where as in a right join the table2 would be the principle table.

Related

Why an 'ON' clause is required in a left outer join

As far as I understand in a left outer join between two tables (say a & b) all the rows of the table on the left side of the join are retrieved regardless of the values in the rows on the right table. Then why do we need an 'ON' clause specifying a condition, something like this:
select * from a LEFT OUTER JOIN b on a.some_column1 = b.some_column2;
Why is there a need for the statement "a.some_column1 = b.some_column2".
A left join would return all the rows from table a, and for each row the matching row in table b, if it exists - if it doesn't, nulls would be returned instead of b's columns. The on clause defines how this matching is done.
An on clause is required since you are "joining", and you need to tell which columns you want to join by. Otherwise you would use traditional from without any where condition to all possible row combinations. But you wanted a join, right?
Yeah, that's pretty much it is.
As far as I understand in a left outer join between two tables (say a & b) all the rows of the table on the left side of the join are retrieved regardless of the values in the rows on the right table.
That is correct in the sense that it says something about what left join on returns, but it isn't a definition of what it returns. left join on returns inner join on rows plus (union all) unmatched left table rows extended by nulls.
inner join on returns the rows of cross join that satisfy the on condition--which could be any condition on the columns. cross join returns every combination of a row from the left table & a row from the right table.
What do you expect outer join without on to mean? In standard SQL outer & inner join have to have an on. inner join on a true condition is the same as cross join. Which has no unmatched left table rows. So if you want outer join with no on to mean outer join on a true condition then, since there are no unmatched rows in the inner join on that condition, the result is also just cross join. (MySQL allows inner join to be used without an on, but it just means cross join.)

Left Outer Join of Same Table (self-join; not first table) Not Returning Null Values

My LEFT OUTER JOIN clause on a table (not the first table) on itself (self-join too) is not returning null values, which skews my SELECT statements. The query is written (table names inconsequential):
Select
SUM(CASE WHEN table2.date =‘day’ and table4.columnX =‘5’ then table3.value1 END),
SUM(CASE WHEN table2.date=’day’ and table4.columnX IS NULL then table3.value2 END)
FROM table1
INNER JOIN table2 on ...
INNER JOIN table3 on ...
LEFT OUTER JOIN table4 on table4.columnX=’5’
In which the first SUM(CASE WHEN) statement uses on one value in table4.columnX - when it is equal to '5' - and the second SUM(CASE WHEN) statement uses all other values - whenever it is not equal to '5'.
As it stands, the query is only returning results where table4.columnX='5', and not where table4.columnX is equal to everything else. As such, it appears the LEFT OUTER JOIN is not returning all null values for table4.columnX<>'5'. I think this may be because the join is written incorrectly. As a note, there are no fields in table4 that can be joined to fields in other tables, so it has to be a self-join of some sort (I believe). Help is appreciated - thank you!
What a LEFT OUTER JOIN will do is take all the rows from the "left table" and conditionally join rows from the "right table". If for a specific row in the "left table", there is no matching row in the "right table", then your "right data values" for the joined row will be NULL.
Your join condition is strange, though, since it doesn't reference another table. If that's really what you want, then you should change it to a CROSS JOIN:
Old: LEFT OUTER JOIN table4 on table4.columnX=’5’
New: CROSS JOIN table4 on table4.columnX=’5’
This will join all rows in table4 where columnX = 5 to each row in your preceding query above. Not sure if that's what you're looking for...

SQL Different between Left join on... and Left Join on..where

I have two sql to join two table together:
select top 100 a.XXX
,a.YYY
,a.ZZZ
,b.GGG
,b.JJJ
from table_01 a
left join table_02 b
on a.XXX = b.GGG
and b.JJJ = "abc"
and a.YYY between '01/08/2009 13:18:00' and '12/08/2009 13:18:00'
select top 100 a.XXX
,a.YYY
,a.ZZZ
,b.GGG
,b.JJJ
from table_01 a
left join table_02 b
on a.XXX = b.GGG
where b.JJJ = "abc"
and a.YYY between '01/08/2009 13:18:00' and '12/08/2009 13:18:00'
The outcome of them is different but I don't understand the reason why.
I would be grateful if I can get some help here.
Whenever you are using LEFT JOIN, all the conditions about the content of the right table should be in the ON clause, otherwise you are effectively converting your LEFT JOIN to an INNER JOIN.
The reason for that is that when a LEFT JOIN is used, all the rows from the left table will be returned. If they are matched by the right table, the values of the matching row(s) will be returned as well, but if they are not matched with any row on the right table, then the right table will return a row of null values.
Since you can't compare anything to NULL (not even another NULL) (Read this answer to find out why), you are basically telling your database to return all rows that are matched in both tables.
However, when the condition is in the ON clause, Your database knows to treat it as a part of the join condition.

What means "table A left outer join table B ON TRUE"?

I know conditions are used in table joining. But I met a specific situation and the SQL codes writes like "Table A join table B ON TRUE"
What will happen based on the "ON TRUE" condition? Is that just a total cross join without any condition selection?
Actually, the original expression is like:
Table A LEFT outer join table B on TRUE
Let's say A has m rows and B has n rows. Is there any conflict between "left outer join" and "on true"? Because it seems "on true" results a cross join.
From what I guess, the result will be m*n rows. So, it has no need to write "left outer join", just a "join" will give the same output, right?
Yes. That's the same thing as a CROSS JOIN.
In MySQL, we can omit the [optional] CROSS keyword. We can also omit the ON clause.
The condition in the ON clause is evaluated as a boolean, so we could also jave written something like ON 1=1.
UPDATE:
(The question was edited, to add another question about a LEFT [OUTER] JOIN b which is different than the original construct: a JOIN b)
The "LEFT [OUTER] JOIN" is slightly different, in that rows from the table on the left side will be returned even when there are no matching rows found in the table on the right side.
As noted, a CROSS JOIN between tables a (containing m rows) and table b containing n rows, absent any other predicates, will produce a resultset of m x n rows.
The LEFT [OUTER] JOIN will produce a different resultset in the special case where table b contains 0 rows.
CREATE TABLE a (i INT);
CREATE TABLE b (i INT);
INSERT INTO a VALUES (1),(2),(3);
SELECT a.i, b.i FROM a LEFT JOIN b ON TRUE ;
Note that the LEFT JOIN will returns rows from table a (a total of m rows) even when table b contains 0 rows.
A cross join produces a cartesian product between the two tables, returning all possible combinations of all rows. It has no on clause because you're just joining everything to everything.
Cross join does not combine the rows, if you have 100 rows in each table with 1 to 1 match, you get 10.000 results, Innerjoin will only return 100 rows in the same situation.
These 2 examples will return the same result:
Cross join
select * from table1 cross join table2 where table1.id = table2.fk_id
Inner join
select * from table1 join table2 on table1.id = table2.fk_id
Use the last method
The join syntax's general form:
SELECT *
FROM table_a
JOIN table_b ON condition
The condition is used to tell the database how to match rows from table_a to table_b, and would usually look like table_a.some_id = table_b.some_id.
If you just specify true, you will match every row from table_a with every row of table_b, so if table_a contains n rows and table_b contains m rows the result would have m*n rows.
Most(?) modern databases have a cleaner syntax for this, though:
SELECT *
FROM table_a
CROSS JOIN table_b
The difference between the pure cross join and left join (where the condition is forced to be always true, as when using ON TRUE) is that the result set for the left join will also have rows where the left table's rows appear next to a bunch of NULLs where the right table's columns would have been.

Is inner join the same as equi-join?

Can you tell me if inner join and equi-join are the same or not ?
An 'inner join' is not the same as an 'equi-join' in general terms.
'equi-join' means joining tables using the equality operator or equivalent. I would still call an outer join an 'equi-join' if it only uses equality (others may disagree).
'inner join' is opposed to 'outer join' and determines how to join two sets when there is no matching value.
Simply put: an equi-join is a possible type of inner-joins
For a more in-depth explanation:
An inner-join is a join that returns only rows from joined tables where a certain condition is met. This condition may be of equality, which means we would have an equi-join; if the condition is not that of equality - which may be a non-equality, greater than, lesser than, between, etc. - we have a nonequi-join, called more precisely theta-join.
If we do not want such conditions to be necessarily met, we can have
outer joins (all rows from all tables returned), left join (all rows
from left table returned, only matching for right table), right join
(all rows from right table returned, only matching for left table).
The answer is NO.
An equi-join is used to match two columns from two tables using explicit operator =:
Example:
select *
from table T1, table2 T2
where T1.column_name1 = T2.column_name2
An inner join is used to get the cross product between two tables, combining all records from both tables. To get the right result you can use a equi-join or one natural join (column names between tables must be the same)
Using equi-join (explicit and implicit)
select *
from table T1 INNER JOIN table2 T2
on T1.column_name = T2.column_name
select *
from table T1, table2 T2
where T1.column_name = T2.column_name
Or Using natural join
select *
from table T1 NATURAL JOIN table2 T2
The answer is No,here is the short and simple for readers.
Inner join can have equality (=) and other operators (like <,>,<>) in the join condition.
Equi join only have equality (=) operator in the join condition.
Equi join can be an Inner join,Left Outer join, Right Outer join
If there has to made out a difference then ,I think here it is .I tested it with DB2.
In 'equi join'.you have to select the comparing column of the table being joined , in inner join it is not compulsory you do that . Example :-
Select k.id,k.name FROM customer k
inner join dealer on(
k.id =dealer.id
)
here the resulted rows are only two columns rows
id name
But I think in equi join you have to select the columns of other table too
Select k.id,k.name,d.id FROM customer k,dealer d
where
k.id =d.id
and this will result in rows with three columns , there is no way you cannot have the unwanted compared column of dealer here(even if you don't want it) , the rows will look like
id(from customer) name(from Customer) id(from dealer)
May be this is not true for your question.But it might be one of the major difference.
The answer is YES, But as a resultset. So here is an example.
Consider three tables:
orders(ord_no, purch_amt, ord_date, customer_id, salesman_id)
customer(customer_id,cust_name, city, grade, salesman_id)
salesman(salesman_id, name, city, commission)
Now if I have a query like this:
Find the details of an order.
Using INNER JOIN:
SELECT * FROM orders a INNER JOIN customer b ON a.customer_id=b.customer_id
INNER JOIN salesman c ON a.salesman_id=c.salesman_id;
Using EQUI JOIN:
SELECT * FROM orders a, customer b,salesman c where
a.customer_id=b.customer_id and a.salesman_id=c.salesman_id;
Execute both queries. You will get the same output.
Coming to your question There is no difference in output of equijoin and inner join. But there might be a difference in inner executions of both the types.