SQL (+)= definition and function - sql

I would like to know what this statement in SQL actually does:
select *
from table
where A (+)= B
I ran it against:
select *
from table
where A = B
and saw the difference but do not know how to formulate an explanation as to what (+)='s functionality is. It seems to me that (+)= is telling it to make it satisfy the condition A = B where available and ignore/enter as "empty" if components are not available.
Also, this statement is ran within a create view statement.
Thanks in advance.

(+)= is a used to show OUTER JOINS. It is not used now and is deprectaed now(as it is not very much readable). (+) denotes the "optional" table in the JOIN. Also I think that + notation is only present for backwards compatibility because Oracle debuted it before the ANSI standard for joins was put in place.
Also note that Oracle recommends that you use the FROM clause OUTER JOIN syntax rather than the Oracle join operator.
Outer join queries that use the Oracle join operator (+) are subject
to the following rules and restrictions, which do not apply to the
FROM clause OUTER JOIN syntax:
You cannot specify the (+) operator in a query block that also contains FROM clause join syntax.
The (+) operator can appear only in the WHERE clause or, in the context of left-correlation (when specifying the TABLE clause) in the
FROM clause, and can be applied only to a column of a table or view.
If A and B are joined by multiple join conditions, then you must use the (+) operator in all of these conditions. If you do not,
then Oracle Database will return only the rows resulting from a
simple join, but without a warning or error to advise you that you
do not have the results of an outer join.
The (+) operator does not produce an outer join if you specify one table in the outer query and the other table in an inner query.
You cannot use the (+) operator to outer-join a table to itself, although self joins are valid. For example, the following statement
is not valid:
-- The following statement is not valid:
SELECT employee_id, manager_id
FROM employees
WHERE employees.manager_id(+) = employees.employee_id;
However, the following self join is valid:
SELECT e1.employee_id, e1.manager_id, e2.employee_id
FROM employees e1, employees e2
WHERE e1.manager_id(+) = e2.employee_id
ORDER BY e1.employee_id, e1.manager_id, e2.employee_id;
The (+) operator can be applied only to a column, not to an arbitrary expression. However, an arbitrary expression can contain
one or more columns marked with the (+) operator.
A WHERE condition containing the (+) operator cannot be combined with another condition using the OR logical operator.
A WHERE condition cannot use the IN comparison condition to compare a column marked with the (+) operator with an expression.

See oracle doc here: http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries006.htm
(go down to outer joins)
An outer join extends the result of a simple join. An outer join
returns all rows that satisfy the join condition and also returns some
or all of those rows from one table for which no rows from the other
satisfy the join condition.

Related

how to write the following sql query in linq

select
coalesce(x.value,a.default_value) as value
from table1 a
left outer join
(
select
b.configid,
b.value
from table2 b
join table3 c on b.dataid=c.id
where c.id=0
)x on a.id=x.configid
where a.key='abc'
For translating SQL to LINQ,
Translate subselects as separate variables
Translate each clause in LINQ clause order, leaving monadic operators (DISTINCT, TOP, etc) as functions applied to the whole LINQ query.
Use table aliases as range variables. Use column aliases as anonymous type field names.
Use anonymous types (new { }) for multiple columns
Left Join is simulated by using a join variable and doing another from from the join variable followed by .DefaultIfEmpty().
Replace coalesce with the conditional operator and a null test.

Oracle SQL: Meaning of (+)= in WHERE clause

I have a question about the using of (+)= in the where clause in Oracle database;
a. id= b.id(+)
Does that mean a left join that a left join on b where a.id=b.id, right?
a.Job_Type(+) = 'Manager'
I don't understand why he uses (+)= here, but not a.Job_Type = 'Manager', are they the same?
it works like LEFT JOIN and RIGHT JOIN depending on the table that column belong to you can read about different types of JOINS here
in your case (+) will return the all records from table which has alias a and only those records from table which has alias b that intersect with table alias a.
The (+) identifies the table that is being outer joined to. The way I was taught, the (+) indicated the table that would have missing rows for which new NULL rows had to be added.
If you look at the alternate left outer join syntaxes that various databases supported before LEFT OUTER JOIN became part of the ANSI standard, the proprietary operator was generally applied to the table that was "missing" rows. DB2 also supports the (+) operator for outer joins in the same way that Oracle does.
Answer: Old Style Oracle Outer Join Syntax - Why locate the (+) on the right side of the equals sign in a Left Outer join?

Oracle left join sql query issue

I have one SQL query in which they have used Left-Join feature and now there is a requirement to convert it into operator (+) syntax. Please guide me how to do it, The query is as written below :
select (some field names)
from
ldcs2.component comp
LEFT JOIN ldcs2.component_detail cd
ON cd.component_id = comp.component_id
LEFT JOIN ldcs2.component_item_breakdown cib
ON cib.component_item_id = cd.component_item_id
So please guide me what does Left-Join specify here and how can we write it into (+) expression.
Also guide me as they have mentioned second mapping table (ldcs2.component_detail) at first in ON condition, whether it would work differently if we write at first in that condition or not?
This is what you could do, but I have to note that personally I prefer the ANSI way.
There are two sides of a join condition. When you use ANSI syntax and code A left join B, you imply that for a record in A, there is no need to be a match on B.
When you put (+) on a specific side of the join condition you imply something like "The field on this side of the condition need not to be matched."
select (some field names)
from
ldcs2.component comp,
ldcs2.component_detail cd,
ldcs2.component_item_breakdown cib
where
cd.component_id (+) = comp.component_id
and cib.component_item_id (+) = cd.component_item_id
You could convert the ANSI/ISO Syntax to Oracle outer join syntax as follows -
SELECT (SOME field names)
FROM ldcs2.component comp,
ldcs2.component_detail cd,
ldcs2.component_item_breakdown cib
WHERE comp.component_id = cd.component_id(+)
AND cd.component_item_id = cib.component_item_id(+)
/
So please guide me what does Left-Join specify here and how can we write it into (+) expression.
For a detailed understanding, see my previous answer on a similar question here https://stackoverflow.com/a/28499208/3989608

Difference visibility in subquery join and where

I had problems with a simple join:
SELECT *
FROM worker wo
WHERE EXISTS (
SELECT wp.id_working_place
FROM working_place wp
JOIN working_place_worker wpw ON ( wp.id_working_place = wpw.id_working_place
AND wpw.id_worker = wo.id_worker)
)
The error I had was ORA-00904: "WO"."ID_WORKER": not valid identifier.
Then I decided to move the union of tables from join clause to the where clause:
SELECT *
FROM worker wo
WHERE EXISTS (
SELECT wp.id_working_place
FROM working_place wp
JOIN working_place_worker wpw ON ( wp.id_working_place = wpw.id_working_place)
WHERE wpw.id_worker = wo.id_worker
)
And this last query works perfect.
Why is not possible to make it in the join? The table should be visible like it is in the where clause. Am I missing something?
In
FROM working_place wp
JOIN working_place_worker wpw ON ...
WHERE ...
the ON clause refers only to the two tables participating in the join, namely wp and wpw. Names from the outer query are not visible to it.
The WHERE clause (and its cousin HAVING is the means by which the outer query is correlated to the subquery. Names from the outer query are visible to it.
To make it easy to remember,
ON is about the JOIN, how two tables relate to form a row (or rows)
WHERE is about the selection criteria, the test the rows must pass
While the SQL parser will admit literals (which aren't column names) in the ON clause, it draws the line at references to columns outside the join. You could regard this as a favor that guards against errors.
In your case, the wo table is not part of the JOIN, and is rejected. It is part of the whole query, and is recognized by WHERE.

What if i dont use Join Keyword in query?

I have a query where i am retrieving data from more than two tables. I am using the filter criteria in where clause but not using any join keyword
select
d.proc_code,
d.dos,
s.svc_type
from
claim_detail d, h_claim_hdr hh, car_svc s
where
d.bu_id="$inp_bu_id"
and
hh.bu_id="$inp_bu_id"
and
s.bu_id="$inp_bu_id"
and
d.audit_nbr="$inp_audit_nbr"
and
hh.audit_nbr="$inp_audit_nbr"
and
d.audit_nbr=hh.audit_nbr
and
s.car_svc_nbr=hh.aut_nbr
Is there a better way of writing this?
Although you are not using a JOIN keyword, your query does perform a JOIN.
A more "modern" way of writing your query (i.e. one following the ANSI SQL standard) would be as follows:
select
d.proc_code,
d.dos,
s.svc_type
from
claim_detail d
join
h_claim_hdr hh on d.audit_nbr=hh.audit_nbr
join
car_svc s on s.car_svc_nbr=hh.aut_nbr
where
d.bu_id="$inp_bu_id"
and
hh.bu_id="$inp_bu_id"
and
s.bu_id="$inp_bu_id"
and
d.audit_nbr="$inp_audit_nbr"
and
hh.audit_nbr="$inp_audit_nbr"
Note that this is simply a modern syntax. It expresses the same query, and it will not impact the performance.
Note that in order for a row to appear in the output of this query, the corresponding rows must exist in all three queries (i.e. it's an inner join). If you would like to return rows of claim_detail for which no h_claim_hdr and / or car_svc existed, use left outer join instead.
A comma in the from clause is essentially the same as a cross join. You really don't want to use a cross join, unless you really know what you are doing.
Proper join syntax has several advantages. The most important of which is the ability to express other types of joins easily and compatibly across databases.
Most people would probably find this version easier to follow and maintain:
select d.proc_code, d.dos, s.svc_type
from claim_detail d join
h_claim_hdr hh
on d.bu_id = hh.bu_id and d.audit_nbr = hh.audit_nbr
car_svc s
on d.bu_id = s.bu_id and s.car_svc_nbr = hh.aut_nbr
where d.bu_id = "$inp_bu_id"
d.audit_nbr = "$inp_audit_nbr";
Using the WHERE clause instead of the JOIN keyword is essentially a different syntax for doing a join. I believe it is called Theta syntax, where using the JOIN clause is called ANSI syntax.
I believe ANSI syntax is almost universally recommended, and some databases require ANSI syntax for outer JOINs.
If you do not use JOIN it will be an implicit inner join. As is in your example with the join criteria on your WHERE clause. So you could me missing records. Lets say you want all records from the first table even if there is not a corresponding record in the second. Your current code would only return the records from the first table that have a matching record in the second.
Joins