SQL如何处理多个值连接

时间:2015-07-29 06:30:31

标签: sql oracle join

我需要通过assignmentsexpatriatesID的组合加入effective_start_dateeffective_end_date表。

我需要获取有关在分配effective_start_dateeffective_end_date期间前往其他国家/地区的员工的数据。但是有必要处理案例,在一次转让期间,已经输入了关于员工前往两个或更多国家的数据 - 我只需要显示一个 - 最后一个或活动的(如果有的话)。

在结果中,我为123人ID获取了多个值,因为在分配表中输入的值不正确 - 我只需要显示此人之一 - 关于他去中国的信息(活跃的)。

所以基本上,如果在一次作业期间(effective_start_dateeffective_end_date之间)有关于他去两个不同国家的信息,我只需要展示一个案例。我需要更正我的select语句,以便以某种方式处理这种情况。

编辑:当有关员工前往另一个国家的2个案例是历史案例时,这也需要工作,所以我不认为可以使用sysdate来完成。

编辑nr.2 - 更新的sql小提琴。我需要同时为人321和第123人展示外派人员 - 这基本上是我的主要目标。

编辑nr.3 - 仍未找到解决方案。 LINK TO SQLFIDDLE

enter image description here

select 
    ass.person_id, 
    ass.effective_start_date,
    ass.effective_end_date,
    exp.date_from, 
    exp.date_to, 
    exp.home_country, 
    exp.host_country
from expatriates exp, assignments ass
where 
    exp.person_id=ass.person_id
and exp.date_to >= ass.effective_start_date
and exp.date_to <= ass.effective_end_date

4 个答案:

答案 0 :(得分:0)

首先,我认为需要更改查询 -

and exp.date_to <= ass.effective_end_dateand exp.date_from <= ass.effective_end_date

现在,如果您想要任何访问过的国家/地区,您可以按人格选择不同的记录,如下所示 -

select 
distinct ass.person_id, 
ass.effective_start_date,
ass.effective_end_date,
exp.date_from, 
exp.date_to, 
exp.home_country, 
exp.host_country
from expatriates exp, assignments ass
where 
exp.person_id=ass.person_id
and exp.date_to >= ass.effective_start_date
and exp.date_from <= ass.effective_end_date

或者,如果您想要一个特定的行,您可以维护另一个状态列,并将其作为&#39; 1&#39;如果访问是活跃的,请将其保留为&#39; 0&#39; 0并使用以下查询 -

select 
ass.person_id, 
ass.effective_start_date,
ass.effective_end_date,
exp.date_from, 
exp.date_to, 
exp.home_country, 
exp.host_country
from expatriates exp, assignments ass
where 
exp.person_id=ass.person_id
and exp.date_to >= ass.effective_start_date
and exp.date_from <= ass.effective_end_date
and exp.status = 1

答案 1 :(得分:0)

我认为你需要加入第三个表格,它将是一个派生表,如下面的“X”:

select 
    ass.person_id, 
    ass.effective_start_date,
    ass.effective_end_date,
    exp.date_from, 
    exp.date_to, 
    exp.home_country, 
    exp.host_country
from expatriates exp, assignments ass, (
    SELECT e.person_id, MAX(e.date_from) md
    FROM expatriates e
    INNER JOIN assignments a ON e.person_id=a.person_id
    and e.date_to >= a.effective_start_date
    and e.date_to <= a.effective_end_date GROUP BY e.person_id) X
where exp.person_id= X.person_id
and exp.date_from= X.md

答案 2 :(得分:0)

我假设一个人被解雇effective_end_date将会更新,并且不再显示expatriates条记录。所以我只选择date_to中的最后一个expatriates。这就是为什么我不明白为什么你需要比较日期范围并从我的位置删除那部分。

SQL FIDDLE DEMO

active_or_last_ass AS (
    SELECT exp.person_id, date_from, max(exp.date_to) max_date
    FROM expatriates exp
    WHERE exp.date_from < sysdate
    GROUP BY exp.person_id, date_from
)   
select 
    ass.person_id, 
    ass.effective_start_date,
    ass.effective_end_date,
    exp.date_from, 
    exp.date_to, 
    exp.home_country, 
    exp.host_country
from 
    active_or_last_ass ala
    inner join expatriates exp 
       on  exp.person_id = ala.person_id
       and exp.date_to = ala.max_date
    inner join assignments ass
       on exp.person_id = ass.person_id

答案 3 :(得分:0)

正如@PuneetPandey已经写过你的逻辑不会捕获所有重叠的时期。

要只获得一行,您可以使用ROW_NUMBER,例如

select *
from
 (
   select 
       ass.person_id, 
       ass.effective_start_date,
       ass.effective_end_date,
       exp.date_from, 
       exp.date_to, 
       exp.home_country, 
       exp.host_country,
       row_number() 
       over (partition by ass.person_id, ass.effective_start_date
             order by exp.date_from) as rn
   from expatriates exp, assignments ass
   where 
       exp.person_id=ass.person_id 
   and exp.date_to >= ass.effective_start_date
   and exp.date_to <= ass.effective_end_date
 ) dt
where rn = 1