2015-08-17 2 views
1

У меня есть 2 таблицы: задания и экспатрианты. У заданий есть их effective_start_date и effective_end_date. Мне нужно показать информацию о назначениях сотрудников и датах, когда они отправились в другую страну (во время назначений). У меня есть оператор select, который позже будет загружать данные в таблицу. Но в таблице есть ограничение, что сочетание assign_id, effective_start_date, effective_end_date должно быть уникальным. А в таблице expatriates у меня нет assign_id. Поэтому я не могу, кажется, присоединиться к 2 таблицам правильно. Я также не могу использовать first_value и отличный, должно быть другое решение.SQL присоединяется только к одному значению при перекрытии дат

with assignments (assignment_id, person_id, effective_start_date, effective_end_date) as (
    select 148713, 123, date '2015-03-16', date '4712-12-31' from dual union all 
    select 13706, 123, date '2015-03-16', date '4712-12-31' from dual union all 
    select 13706, 123, date '2015-01-01', date '2015-03-15' from dual 
), 
expatriates (person_id, date_from, date_to, home_country, host_country, valid_from, valid_to) as (
    select 123, date '2015-03-16', date '2016-04-15', 'TEST', 'TEST', date '2015-03-16', date'2015-04-15' from dual union all 
    select 123, date '2015-01-01', date '2015-03-15', 'TEST2', 'TEST2', date '2015-01-01', date'2015-03-15' from dual union all 
    select 123, date '2014-04-16', date '2016-06-15', 'TEST1', 'TEST1', date '2015-04-16', date'2016-06-15' from dual 
) 

select 
    a.assignment_id, 
    a.person_id, 
    a.effective_start_date, 
    a.effective_end_date, 
    subq.date_from, 
    subq.date_to, 
    subq.home_country, 
    subq.host_country 
from expatriates subq, assignments a 
where 
    subq.person_id=a.person_id 
and subq.valid_from <= a.effective_end_date 
and subq.valid_to >= a.effective_start_date 

Edit: забыл упомянуть, что я не могу использовать оператор ИЛИ, потому что присоединяется мне нужно сделать, на самом деле внешние соединения, и я не могу использовать объединение все, чтобы исправить эту проблему. Я использовал внутренние соединения только для примера.

Редактировать nr. 2: до сих пор нет решения для этого?

+0

Какого результата вы хотите (для ваших Пример данных)? Мне кажется, что ваш запрос в порядке. –

ответ

0
select 
    a.assignment_id, 
    a.person_id, 
    a.effective_start_date, 
    a.effective_end_date, 
    subq.date_from, 
    subq.date_to, 
    subq.home_country, 
    subq.host_country 
from expatriates subq, assignments a 
where 
    subq.person_id=a.person_id 
and (
    (subq.valid_from >= a.effective_start_date and subq.valid_from <= a.effective_end_date) 
    or 
    (subq.valid_to >= a.effective_start_date and subq.valid_to <= a.effective_end_date) 
    ) 
+0

Это не работает для меня, комбинации id, effective_start_date и effective_end не уникальны. И я не упоминал об этом сначала, но я не могу использовать или оператор, потому что соединения, которые я сделал, фактически будут внешними соединениями (я просто использовал внутренние соединения только для примера). И я не могу использовать инструкцию OR во внешнем соединении. – user3014914

0

Возможно, вы могли бы использовать законы Де Моргана в сочетании с МЕЖДУ ... И чтобы избежать ОР?

Что-то вроде этого: Если предположить, что положение с или вы хотите, чтобы избежать такой:

(
(subq.valid_from >= a.effective_start_date and subq.valid_from <= a.effective_end_date) 
OR 
(subq.valid_to >= a.effective_start_date and subq.valid_to <= a.effective_end_date) 
) 

Использование BETWEEN ... И это можно записать в виде:

(
(subq.valid_from BETWEEN a.effective_start_date AND a.effective_end_date) 
OR 
(subq.valid_to BETWEEN a.effective_start_date AND a.effective_end_date) 
) 

De Моргана законы говорят, что NOT A OR NOT B эквивалентен NOT (A AND B). Так если предположить, что

  1. NOT A является (subq.valid_from BETWEEN a.effective_start_date AND a.effective_end_date) и
  2. NOT B является (subq.valid_to BETWEEN a.effective_start_date AND a.effective_end_date),

следует, что

  1. A является (subq.valid_from NOT BETWEEN a.effective_start_date AND a.effective_end_date) и
  2. B является (subq.valid_to NOT BETWEEN a.effective_start_date AND a.effective_end_date).

(Пожалуйста, отметьте неимущие до того, как посредники.)

В сочетании с законом де Моргана, предложение может быть записано без OR:

NOT (
subq.valid_from 
    NOT BETWEEN a.effective_start_date 
    AND a.effective_end_date 
AND 
subq.valid_to 
    NOT BETWEEN a.effective_start_date 
    AND a.effective_end_date 
)