通过ID和日期范围的组合进行SQL连接

时间:2015-07-16 09:50:06

标签: sql oracle date join

有表格 - 作业和国家/地区。

分配存储有关员工历史分配的历史数据,三个主要字段是 - person_id,effective_start_date和effective_end_date。

各国存储有关出国旅行的员工的信息 - 其中的重要字段是person_id,date_from,date_to,home_country,host_country。

我需要做以下事情:我需要显示所有作业,以及员工在作业期间任何时候去过的国家/地区。这意味着我需要通过外连接加入它们,但我可以加入它们的唯一方法是通过person_id,但每个表中有多个条目(相同ID)

enter image description here 所以我做的是这样的:

select * 
from assignments ass, employees emp
where
ass.person_id=emp.person_id
AND (emp.date_from(+) >= ass.assignment_start_date AND emp.date_to(+) <= ass.assignment_end_date)
OR (emp.date_from(+) >= ass.assignment_start_date AND emp.date_to(+) >= ass.assignment_end_date) 

但它不起作用,因为oracle不允许我在外连接中创建OR语句。我尝试使用union all方法,但返回的值不是我所期望的 - 有一些缺失的值,所以逻辑不正确的eighter。如果您有任何建议,请使用我提供的相同语法(oracle语法)发布它们,其中在where子句中进行连接,因此我更容易理解。

2 个答案:

答案 0 :(得分:0)

要获得所需的结果,您可以使用以下方法:

  • 使用ANSI样式的JOIN而不是过时的Oracle语法(它们更灵活,恕我直言也更具可读性)
  • 连接各国(例如使用LISTAGG

查询:

select ass.person_id, 
       assignment_start_date, 
       assignment_end_date,   
       listagg(home_country ||'-' || host_country, ';')
          within group (order by date_from) as countries
  from assignments ass
  left join employees emp
    on ass.person_id = emp.person_id
   AND ((emp.date_from >= ass.assignment_start_date AND
       emp.date_from <= ass.assignment_end_date)
    OR (emp.date_to >= ass.assignment_start_date AND
       emp.date_to <= ass.assignment_end_date))
group by ass.person_id, assignment_start_date, assignment_end_date

SQL Fiddle

答案 1 :(得分:0)

我认为这就是你想要的,使用oracle语法

select ass.person_id, assignment_start_date, assignment_end_date, 
emp.home_country,emp.host_country
from assignments ass, employees emp
where
ass.person_id=emp.person_id(+)
AND (emp.date_from(+) <= ass.assignment_end_date AND emp.date_to(+) >= ass.assignment_end_date)

SQLFiddle