我不明白如何只加入第一个匹配的行。如果我通过person_id和dates的组合加入,则查询将返回多个值。在这种情况下,如果join返回多个值,我只希望显示此联接中的一行。预期结果 - assignment_id,effective_start_date,effective_end_date的组合是唯一的。
让我最困扰的是我没有唯一的标识符,只有日期。如果来自外派人员表的两个日期范围适合分配有效_start_date,effective_end_date范围我只需要显示一行。
请提供Oracle语法(如我的代码示例)。
with assignments (assignment_id, person_id, effective_start_date, effective_end_date) as (
select 456, 123, date '2015-01-01', date '2015-03-15' from dual union all
select 456, 123, date '2015-03-16', date '4712-12-31' from dual union all
select 975, 123, date '2015-03-16', date '4712-12-31' from dual
),
expatriates (person_id, home_country, host_country, date_from, date_to, valid_from, valid_to)
as
(
select 123, 'TEST2', 'TEST2', date '2015-01-01', date '2015-03-15', date '2015-01-01', date '2015-03-15' from dual union all
select 123, 'TEST1', 'TEST1', date '2015-04-16', date '2016-06-15', date '2015-04-16', date '2016-06-15' from dual union all
select 123, 'TEST', 'TEST', date '2015-03-16', date '2016-04-15', date '2015-03-16', date '2015-04-15' from dual
)
select
a.assignment_id,
a.person_id,
a.effective_start_date,
a.effective_end_date,
subq.home_country,
subq.host_country,
subq.date_from,
subq.date_to
from assignments a
, expatriates subq
where
a.person_id=subq.person_id
and subq.valid_from <= a.effective_end_date
and subq.valid_to >= a.effective_start_date
答案 0 :(得分:1)
这是子查询中的分析排名函数的经典用例,可以对其进行过滤以返回所需的子集。在这种情况下,我使用了ROW_NUMBER(),因为你还没有提供丢弃行的任何标准,所以假设确实哪个实际行是&#34;第一个&#34;行。
select assignment_id,
person_id,
effective_start_date,
effective_end_date,
date_from,
date_to,
home_country,
host_country
from (
select
a.assignment_id,
a.person_id,
a.effective_start_date,
a.effective_end_date,
e.date_from,
e.date_to,
e.home_country,
e.host_country,
row_number() over (partition by a.assignment_id, a.effective_start_date
order by e.date_from) rn
from assignments a
join expatriates e
on (a.person_id=e.person_id )
where e.valid_from <= a.effective_end_date
and e.valid_to >= a.effective_start_date
)
where rn = 1
order by 1, 3, 2
/
这将从您的示例数据中返回以下行:
28* order by 1, 3, 2
ASSIGNMENT_ID PERSON_ID EFFECTIVE EFFECTIVE DATE_FROM DATE_TO HOME_ HOST_
------------- ---------- --------- --------- --------- --------- ----- -----
456 123 01-JAN-15 15-MAR-15 01-JAN-15 15-MAR-15 TEST2 TEST2
456 123 16-MAR-15 31-DEC-12 16-MAR-15 15-APR-16 TEST TEST
975 123 16-MAR-15 31-DEC-12 16-MAR-15 15-APR-16 TEST TEST
3 rows selected.
SQL>
Oracle拥有大量简洁的分析功能。 Find out more
答案 1 :(得分:0)
我不确定从您需要的外派人员表中过滤记录的标准,但作为示例,我们可以按date_from字段进行过滤:
with assignments (assignment_id, person_id, effective_start_date, effective_end_date) as (
select 456, 123, date '2015-01-01', date '2015-03-15' from dual union all
select 456, 123, date '2015-03-16', date '4712-12-31' from dual union all
select 975, 123, date '2015-03-16', date '4712-12-31' from dual
),
expatriates (person_id, home_country, host_country, date_from, date_to, valid_from, valid_to)
as
(
select 123, 'TEST2', 'TEST2', date '2015-01-01', date '2015-03-15', date '2015-01-01', date '2015-03-15' from dual union all
select 123, 'TEST1', 'TEST1', date '2015-04-16', date '2016-06-15', date '2015-04-16', date '2016-06-15' from dual union all
select 123, 'TEST', 'TEST', date '2015-03-16', date '2016-04-15', date '2015-03-16', date '2015-04-15' from dual
)
select
a.assignment_id,
a.person_id,
a.effective_start_date,
a.effective_end_date,
subq.home_country,
subq.host_country,
subq.date_from,
subq.date_to
from assignments a, expatriates subq
where
a.person_id=subq.person_id
and subq.valid_from <= a.effective_end_date
and subq.valid_to >= a.effective_start_date
and subq.date_from =
(
select
max(date_from)
from expatriates sq2
where
sq2.person_id = a.person_id and
sq2.valid_from <= a.effective_end_date and
sq2.valid_to >= a.effective_start_date
)