Oracle SQL: How to convert multiple (+) WHERE clauses to LEFT JOINS? [duplicate] - sql

This question already has answers here:
Oracle "(+)" Operator
(4 answers)
Closed last month.
I'm trying to convert some Oracle SQL code to regular SQL and am having trouble with the numerous variables in the SELECT statement, tables in the FROM statement, and (+) WHERE statements.
I have looked through similar posts but all provide simple examples with just 2 variables, 2 tables, and 1 (+) WHERE statement. I'm not sure how to apply what I'm seeing from the other forum posts to multiple variables, tables, and (+) WHERE statements.
SELECT
a.ID,
c.var1,
d.var2
FROM a, b, c, d, x, y
WHERE a.ID(+) = b.ID
AND c.var1(+) = b.var1
AND x.id(+) = y.id;
I tried to convert all the (+) WHERE statements to LEFT JOINs as shown below. I did 3 LEFT JOINS, one for each (+) WHERE statement:
SELECT
a.ID,
c.var1,
d.var2
FROM a, b, c, d, x, y
WHERE b.ID in
(SELECT b.ID
FROM b
LEFT JOIN a
ON a.ID = b.ID)

The query:
SELECT a.ID,
c.var1,
d.var2
FROM a, b, c, d, x, y
can be rewritten using ANSI-join syntax as:
SELECT a.ID,
c.var1,
d.var2
FROM a
CROSS JOIN b
CROSS JOIN c
CROSS JOIN d
CROSS JOIN x
CROSS JOIN y
If you add in the WHERE clause then WHERE c.var1(+) = b.var1 converts the CROSS JOIN to a LEFT OUTER JOIN from b to c. Similarly for the other join conditions.
Which gives you:
SELECT a.ID,
c.var1,
d.var2
FROM b
LEFT OUTER JOIN a ON a.ID = b.ID
LEFT OUTER JOIN c ON c.var1 = b.var1
CROSS JOIN d
CROSS JOIN y
LEFT OUTER JOIN x ON x.id = y.id;
fiddle

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.

FROM Statement Giving an Error (3 Sources)

I am trying to SELECT a few things from tables A,B, and C, but when I try to LEFT JOIN, I keep getting an error. My code currently looks like this:
FROM (A LEFT JOIN B ON A.id = B.id), C
Am I not allowed to left join two tables and include the entirety of a third?
Thanks for your help.
EDIT
Here is a sample code:
SELECT A.ID, A.place, A.receipt, D.State, A.service, B.Description, C.ID, C.receipt, C.Source
FROM B, (A LEFT JOIN C ON A.receipt = C.receipt), D;
Access doesn't support combining cross-joins with other joins, so you will have to do the left join in a subquery, and then the cross-join:
FROM (SELECT * FROM A LEFT JOIN B ON A.id = B.id) As D, C

T-SQL: Wild Card as table name alias in select statement possible?

This is more of a curiosity than an actual applied question. Say you have a statement with multiple joins such as:
SELECT
a.name,
b.salary,
c.x
FROM
[table1] a
INNER JOIN [table2] b
ON a.key = b.key
INNER JOIN [table3] c
ON b.key = c.key
Now, say you were to make several more joins to other tables whose schema was unfamiliar, however you know:
the keys on which to make the join
that several of those tables has a column with the the name 'x'.
Is it possible to select 'x' from all tables that contain it, without explicitly referring to the table alias. So it would ave a similar results as this (if it were possible)
SELECT
a.name,
b.salary,
*.x
...
No this isn't possible.
You can use a.* to get all columns from a but it is not valid to use a wildcard as the table name.
#Martin Smith is correct that you can't use *.x and refer to columns from multiple tables. There is however a way to write a query that shows all columns x from tables where they exist without breaking if one or more of the tables do not have such column. It's a rather complicated way that (mis)uses scope resolution.
Lets say that some of the tables (b and d in the example) have a column named x, while some others (c here) do not have such column. Then you can replace INNER joins with CROSS APPLY and LEFT joins with OUTER APPLY and a query with:
SELECT
a.name,
a.salary,
b.x AS bx,
'WITHOUT column x' AS cx,
d.x AS dx
FROM
a
INNER JOIN b
ON a.aid = b.aid
LEFT JOIN c
ON a.aid = c.aid
LEFT JOIN d
ON a.aid = d.aid ;
would be written as:
SELECT
a.name,
a.salary,
bx,
cx,
dx
FROM
( SELECT a.*,
'WITHOUT column x' AS x
FROM a
) a
CROSS APPLY
( SELECT x AS bx
FROM b
WHERE a.aid = b.aid
) b
OUTER APPLY
( SELECT x AS cx
FROM c
WHERE a.aid = c.aid
) c
OUTER APPLY
( SELECT x AS dx
FROM d
WHERE a.aid = d.aid
) d ;
Tested at SQL-Server 2008: SQL-Fiddle

How to use oracle outer join with a filter where clause

If i write a sql:
select *
from a,b
where a.id=b.id(+)
and b.val="test"
and i want all records from a where corresponding record in b does not exist or it exists with val="test", is this the correct query?
You're much better off using the ANSI syntax
SELECT *
FROM a
LEFT OUTER JOIN b ON( a.id = b.id and
b.val = 'test' )
You can do the same thing using Oracle's syntax as well but it gets a bit hinkey
SELECT *
FROM a,
b
WHERE a.id = b.id(+)
AND b.val(+) = 'test'
Note that in both cases, I'm ignoring the c table since you don't specify a join condition. And I'm assuming that you don't really want to join A to B and then generate a Cartesian product with C.
Move the condition into the JOIN clause and use the ANSI standard join pattern.
SELECT NameYourFields,...
FROM A
LEFT OUTER JOIN B
ON A.ID = B.ID
AND B.VAL = 'test'
INNER JOIN C
ON ...
A LEFT OUTER JOIN is one of the JOIN operations that allow you to specify a join clause. It preserves the unmatched rows from the first (left) table, joining them with a NULL row in the shape of the second (right) table.
So you can do as follows :
SELECT
FROM a LEFT OUTER JOIN b
ON a.id = b.id
--Note that you have used double quote "test" which is not used for varchar in SQL you should use single quote 'test'
AND b.val = 'test';
SELECT * FROM abc a, xyz b
WHERE a.id = b.id
AND b.val = 'test'

Is it possible to do a 3 table join in MS-Access?

I try to do a 3-table join in Access and it will not work. Is it possible?
I once had a problem when I tried
select
x,
y
from
A inner join
B on k=l inner join
C on f=g
This didn't work. But it works with parantheses:
select
x,
y
from (
A inner join
B on k=l ) inner join
C on f=g
All the various types of multi-table joins that are available in other flavour of SQL are permitted in MS-Access/Jet. For example, here's a straight three-table hierarchical example (a bit more real-world than the other answers here):
SELECT
x.FirstName,
x.Surname,
r.RegionName,
c.CountryName
FROM
(Customer x LEFT JOIN Region r
ON r.ID=x.RegionID)
LEFT JOIN Country c
ON c.ID=r.CountryID
Or did you want to know how to do it using the Visual Designer in MS-Access?
Yes, it's possible:
Select *
From A, B, C
Where A.a = B.b
And A.c = C.c
or
Select *
From A, B, C
Where A.a = B.b
And B.c = C.c
Access can do most types of joins (apart from a full outer) I wonder with your 3 table join if you are doing an ambiguous outer join? Have a look at this KB article for an explanation
support.microsoft.com/kb/124937