How does SQL process "wrapped joins"? - sql

I'm going through some older code, and one query is laid out in the following manner:
FROM (A INNER JOIN (B LEFT JOIN C ON B.ID2 = C.ID2) ON A.ID1= B.ID1)
I'm confused as to how this would actually be processed? What's the difference between the above and below?
FROM A
INNER JOIN B ON A.ID1 = B.ID1
LEFT JOIN C on B.ID2 = C.ID2

The first code uses subquery. I used the Northwind data base to test this if both codes produce the same results.
I first used the first query:
Select *
From(Categories c JOIN (Products p Left Join Suppliers s on p.SupplierID=s.SupplierID) on c.CategoryID=p.CategoryID)
Then I used the following query:
Select *
From Categories c
Join Products p on c.CategoryID=p.CategoryID
Left Join Suppliers s on p.SupplierID=s.SupplierID
It seems they produce the exact same result. Furthermore, in both queries I changed Inner Join with Left Join and and Left Join with Inner join. And I tested it and they seem to give same results. So I think they are the same.

Related

Difference between JOIN expressions in Presto SQL

I would like to ask the difference between the following join expressions and in what conditions is Method 2 more preferred than Method 1.
You can imagine tables a, b and c to be CTEs for i.e. With a AS (xxxxx), b AS (xxxxx), and c AS (xxxxx).
Method 1:
Select
a.customerid,
b.customerage,
b.customermobile,
a.itemid,
c.itemname
from a
LEFT JOIN b on
a.customerid = b.customerid
LEFT JOIN c on
a.itemid = c.itemid
Method 2:
Select
a.customerid,
b.customerage,
b.customermobile,
a.itemid,
c.itemname
from ((( a
LEFT JOIN b on
(a.customerid = b.customerid))
LEFT JOIN c on
(a.itemid = c.itemid))
There is no difference. This structure:
from a left join
b left join
c
is exactly defined as
from (a left join
b
) left join
c
(I'm leaving out the on clauses to simplify the explanation.)
Note: The order of evaluation is important for outer joins. But even for inner joins, the above is subtly different from:
from a left join
(b left join
c
)
For instance, this won't even parse if the on clause between b and c references a as well.

Oracle join's order

I have a sql sentence.
select a.*,b.*,c.*
from a
inner join b
on a.id=b.id
left join c
on b.id=c.id
but I not konw it is execute inner join first .then create a temporary table such as temp .and finaly temp left join c. inner join ,left join and right join do they have same level of execution.Thank you!
SQL is not a procedural language. A SQL query describes the result set being produced. When interpreting a query, the join order is from left to right. So, in your query, the result set is the one produced by an inner join on a and b with that result being left joined to c.
You can add parentheses to avoid ambiguity:
from (a inner join
b
on a.id = b.id
) left join
c
on b.id = c.id
But that is unnecessary.
That is logically how the query is processed. The optimization engine can choose many different ways of executing the query, some of which might be pretty unrecognizable as relating to this particular query. The only guarantee is what the result set looks like.

Right Outer Join to Left Outer join

I have a query in sqlserver that needs to be translated to sqlite3, but this query uses "Right outer join", the problem is that sqlite doesn't support this operator yet.
how can I translate this query to use only "left outer join" instead of "right" outer join?
SELECT *
FROM P RIGHT OUTER JOIN
CL RIGHT OUTER JOIN
C LEFT OUTER JOIN
CC ON C.IDC = CC.RIDC ON
C.IDC = C.RIDCL ON P.IDP = C.RIDP
Thanks.
PS: I'm having trouble also with the sqlite joins precedence and associativity, don't know how it may alter the final result by reordering the tables.
In this query, the table c is in the middle. So that is driving the query.
Your on conditions are in strange places. I am guessing this is what you mean:
SELECT *
FROM C LEFT OUTER JOIN
CC
ON C.IDC = CC.RIDC LEFT OUTER JOIN
P
ON P.IDP = C.RIDP LEFT OUTER JOIN
CL
ON CL.IDC = C.RIDCL
An additional remark on the join syntax.
Most people write
Tab1 JOIN Tab2 ON ... JOIN Tab3 ON ... JOIN Tab4 ON ...
probably because this is the "natural" way, one table after the other.
But your joins use the "other" syntax i usually try to avoid.
Tab1 JOIN Tab2 JOIN Tab3 JOIN Tab4 ON ... ON ... ON ...
Logically joins are processed in the order of ON, so adding parens results in:
( P
RIGHT OUTER JOIN
( CL
RIGHT OUTER JOIN
( C
LEFT OUTER JOIN
CC
ON C.IDC = CC.RIDC
) p
ON C.IDC = C.RIDCL
)
ON P.IDP = C.RIDP
)
Rewriting it results in a join order C-CC-CL-P. This is not the C-CC-P-CL order Gordon used, but in your case this doesn't matter, because C is the main table :-)

Outer join in oracle with ANSI standard

select ...
from A left outer join B on (B.x=A.x)
left outer join C on (C.y=A.y)
want to add one additional join of table D with table C with a condition D.z=C.z
select ...
from A left outer join B on (B.x=A.x)
left outer join C on (C.y=A.y), D inner join C on (D.z=C.z)
however, query does not work after adding this part " , D inner join C on (D.z=C.z) ".
Any suggestions ?
You should just add left outer join D on (D.z=C.z). If you use INNER JOIN you remove rows from A and B which not connected with C and D
select ...
from A left outer join B on (B.x=A.x)
left outer join C on (C.y=A.y)
left outer join D on (D.z=C.z)
My understanding is that it is not just table C but the result of an inner join between C and D that you want to outer-join to table A.
If that is so, then #valex's suggestion is an alternative but equivalent way to represent that logic.
In some SQL products the syntax would allow you to write out the logic exactly as intended:
…
FROM
A
LEFT JOIN B ON (B.x=A.x)
LEFT JOIN
C
INNER JOIN D ON (D.z=C.z)
ON (C.y=A.y)
Oracle doesn't support such syntax. But you could rewrite the query like this in order to make the syntax more closely reflect the intended logic:
…
FROM
C
INNER JOIN D ON (D.z=C.z)
RIGHT JOIN A ON (C.y=A.y)
LEFT JOIN B ON (B.x=A.x)
Now it is clear that C and D are supposed to be inner-joined and their result should be outer-joined to A (A being on the outer side of the join, which is the right side this time, hence RIGHT JOIN), followed by an outer join of B to A.
Still, as I said, #valex's is an equivalent suggestion that should produce the same results.

Joining multiple tables in SQL

Can sombody Explains me about joins?
Inner join selects common data based on where condition.
Left outer join selects all data from left irrespective of common but takes common data from right table and vice versa for Right outer.
I know the basics but question stays when it comes to join for than 5, 8, 10 tables.
Suppose I have 10 tables to join. If I have inner join with the first 5 tables and now try to apply a left join with the 6th table, now how the query will work?
I mean to say now the result set of first 5 tables will be taken as left table and the 6th one will be considerded as Right table? Or only Fifth table will be considered as left and 6th as right? Please help me regarding this.
When joining multiple tables the output of each join logically forms a virtual table that goes into the next join.
So in the example in your question the composite result of joining the first 5 tables would be treated as the left hand table.
See Itzik Ben-Gan's Logical Query Processing Poster for more about this.
The virtual tables involved in the joins can be controlled by positioning the ON clause. For example
SELECT *
FROM T1
INNER JOIN T2
ON T2.C = T1.C
INNER JOIN T3
LEFT JOIN T4
ON T4.C = T3.C
ON T3.C = T2.C
is equivalent to (T1 Inner Join T2) Inner Join (T3 Left Join T4)
It's helpful to think of JOIN's in sequence, so the former is correct.
SELECT *
FROM a
INNER JOIN b ON b.a = a.id
INNER JOIN c ON c.b = b.id
LEFT JOIN d ON d.c = c.id
LEFT JOIN e ON e.d = d.id
Would be all the fields from a and b and c where all the ON criteria match, plus the values from d where its criteria match plus all the contents of e where all its criteria match.
I know RIGHT JOIN is perfectly acceptable, but I've found in my experience that it's unnecessary - I almost always just join things from left to right.
> Simple INNER JOIN VIEW code...
CREATE VIEW room_view
AS SELECT a.*,b.*
FROM j4_booking a INNER JOIN j4_scheduling b
on a.room_id = b.room_id;
You can apply join like this..
select a.*,b.*,c.*,d.*,e.*
from [DatabaseName].[Table_a] a
INNER JOIN [DatabaseName].[Table_b] b ON a.id = b.id
INNER JOIN [DatabaseName].[Table_c] c ON b.id=c.id
INNER JOIN [DatabaseName].[Table_d] d on c.id=d.id
INNER JOIN [DatabaseName].[Table_e] e on d.id=e.id where a.con=5 and
b.con=6
Here, at place of a.* and in where condition, you can show column(filed) which you like and according condition in where condition. You can insert more table and database as per your choice. But mind that you need to mention database name and alias if you work in different database.
Just tried the following from the Example DataBase given in W3School. Worked Fine for me.
SELECT Orders.OrderID, Customers.CustomerName, Orders.OrderDate, Products.ProductName, Products.ProductID
FROM Orders
INNER JOIN Products
INNER JOIN Customers
ON Orders.CustomerID=Customers.CustomerID;
Join used to combine rows from two or more tables, based on a related column between them. This example from Adventure works:
SELECT a.[EmailAddress],b.[FirstName],b.[LastName],c.[PhoneNumber],d.[Name]
FROM [Person].[EmailAddress] a
INNER JOIN [Person].[Person] b
ON a.BusinessEntityID = b.BusinessEntityID
INNER JOIN [Person].[PersonPhone] c
ON b.BusinessEntityID = c.BusinessEntityID
INNER JOIN [Person].[PhoneNumberType] d
ON c.phoneNumberTypeID = d.phoneNumberTypeID