Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SQL Alternative for 'OR' in where clause when using outer join

I have the following query:

select * from
from assignments dah, employees emp 
where 
    dah.person_id=emp.person_id(+)
and 
(dah.effective_end_date between emp.date_from(+) and emp.date_to(+)
and dah.effective_end_date between emp.valid_from(+) and emp.valid_to(+))
or   
(dah.effective_start_date between emp.date_from(+) and emp.date_to(+)
and dah.effective_start_date between emp.valid_from(+) and emp.valid_to(+))

I get the following message: 'outer join operator (+) not allowed in operand of OR or IN'. I know about using 2 unions with inner joins is a solution, but I can't use it because I actually have a lot of code (code I provided is just an example).

Edit: i need this done via oracle syntax, because i work with data warehousing and our ETL doesn't fully support explicit syntax. Maybe there is something i am not seeing and this can be written differently?

Edit nr.2 : Maybe date overlapping logic can somehow be implemented without using OR and with oracle syntax?

like image 297
user3014914 Avatar asked Aug 04 '15 11:08

user3014914


People also ask

Can I use WHERE clause in outer join?

Introduction. Although an ON clause is required for each operation in an outer join in a FROM clause, an outer join can itself also include a WHERE clause. Any restriction in the WHERE clause is applied only to the table that is the final result of the outer join.

How do you use outer join with or operator?

You apply the outer join operator (+) in parentheses following a column name within predicates that refer to columns from two tables, as shown in the following examples: The following query performs a left outer join of tables T1 and T2. Include both tables in the FROM clause, separated by a comma.

Which operator can be used in an outer join condition and or not in?

The SQL OUTER JOIN returns all rows from both the participating tables which satisfy the join condition along with rows which do not satisfy the join condition. The SQL OUTER JOIN operator (+) is used only on one side of the join condition only.

Can we use WHERE clause with joins in SQL?

To use the WHERE clause to perform the same join as you perform using the INNER JOIN syntax, enter both the join condition and the additional selection condition in the WHERE clause. The tables to be joined are listed in the FROM clause, separated by commas. This query returns the same output as the previous example.


1 Answers

Use explicit left join syntax:

select *
from employees emp left join
     assignments dah 
     on dah.person_id = emp.person_id and
        ((dah.effective_end_date between emp.date_from and emp.date_to and
          dah.effective_end_date between emp.valid_from and emp.valid_to
         ) or
         (dah.effective_start_date between emp.date_from and emp.date_to and
          dah.effective_start_date between emp.valid_from and emp.valid_to
         )
        );

A simple rule is never to use a comma in the from clause. Always use explicit join syntax.

Note: Technically, your outer join syntax would have the tables in the other order:

from assignments dah left join
     employees emp 
     on . . .

I swapped them on purpose. The left join keeps all rows in the first table, even those with no matches. The + syntax is harder to follow. The + goes on the side that would get the NULL values. However, to me, this seems less likely that the unmatched rows are in the assignments table.

If you have proper foreign key relationships, then all the assignments should have a correct person. I may not understand you data, however, and you might want to reverse your tables for what you are really trying to do.

EDIT:

As for overlaps, I would be inclined to use the simpler:

     on dah.person_id = emp.person_id and
        (dah.effective_end_date >= emp.date_from and
         dah.effective_start_date <= emp.date_to 
        )

You can even write this using the archaic + notation, if you like. Also note: these do not do exactly the same things. This will detect overlaps where one period is entirely embedded in another period.

like image 80
Gordon Linoff Avatar answered Sep 22 '22 19:09

Gordon Linoff