1

我需要找到service.service_idservice.nameservice.date_begin每一行中bonus表最接近service.date_beginservice.date_begin <= bonus.date_begin。如果有多於一個service與這樣的date_begin,返回任何service(例如與最大service.service_idservice.rowid)。如果沒有這樣的service,請返回NULL查找排在相關表格與最接近的日期

bonus表(bonus_id是PK):

bonus_id date_begin 
-------------------- 
1   2010-04-12 
2   2010-04-20 

service表(service_id被PK):

bonus_id service_id name date_begin 
-------------------------------------- 
1   1   'a' 2010-04-10 
1   2   'b' 2010-04-11 
1   3   'c' 2010-04-11 
1   4   'd' 2010-04-15 
2   5   'e' 2010-04-22 

希望的輸出:

bonus_id bonus_date_begin service_id service_name service_date_begin 
------------------------------------------------------------------------ 
1   2010-04-12  3   'c'   2010-04-11 
2   2010-04-20  NULL  NULL   NULL 

數據庫:Oracle 11.2

人口腳本:

create table bonus (
    bonus_id number primary key, 
    date_begin date 
); 
create table service (
    bonus_id number references bonus(bonus_id), 
    service_id number primary key, 
    name varchar2(1), 
    date_begin date 
); 
insert into bonus values (1, date '2010-04-12'); 
insert into bonus values (2, date '2010-04-20'); 
insert into service values (1, 1, 'a', date '2010-04-10'); 
insert into service values (1, 2, 'b', date '2010-04-11'); 
insert into service values (1, 3, 'c', date '2010-04-11'); 
insert into service values (1, 4, 'd', date '2010-04-15'); 
insert into service values (2, 5, 'e', date '2010-04-22'); 
commit; 
+0

是列的service_id和在採樣數據bonus_id翻轉? –

+0

@vkp謝謝!編輯。 – avd

回答

1
SELECT b.bonus_id, 
     MAX(b.date_begin) AS bonus_date_begin, 
     MAX(s.service_id) KEEP (DENSE_RANK LAST ORDER BY s.date_begin, s.service_id) 
     AS service_id, 
     MAX(s.name  ) KEEP (DENSE_RANK LAST ORDER BY s.date_begin, s.service_id) 
     AS service_name, 
     MAX(s.date_begin) KEEP (DENSE_RANK LAST ORDER BY s.date_begin, s.service_id) 
     AS service_date_begin 
FROM bonus b 
     LEFT OUTER JOIN 
     service s 
     ON (b.bonus_id = s.bonus_id AND s.date_begin < b.date_begin) 
GROUP BY b.bonus_id; 

輸出

BONUS_ID BONUS_DATE_BEGIN SERVICE_ID SERVICE_NAME SERVICE_DATE_BEGIN 
-------- ---------------- ---------- ------------ ------------------ 
1  2010-04-12  3   c   2010-04-11 
2  2010-04-20  NULL  NULL   NULL 
+0

謝謝!但1)'s.date_begin <= b.date_begin' 2)'b.bonus_id'是唯一的,所以不需要'group by'和'max(b.date_begin)'。 – avd

+0

@sltn這是必需的,因爲''bonus'表中的每行都有'service'表中有多行連接。 – MT0

+0

好的,我明白了。只是好奇,爲什麼你更喜歡'b.batus_id,b.date_begin'上的'max(b.date_begin)'over'group? – avd

1

試試這個代碼,這會給你所需的輸出。

select bonus.bonus_id ,bonus.date_begin as bonus_date_begin,max(service.service_id) as service_id, 
max(service.date_begin) as service_date_begin 
from bonus left join service 
on bonus.bonus_id=service.bonus_id 
and service.date_begin <= bonus.date_begin 
group by bonus.bonus_id ,bonus.date_begin 
+0

這隻適用於'service.date_begin'和'service.service_id'都以相同順序遞增的情況。如果數據是'service.service_id'是遞減順序(或隨機順序),那麼'service_id'可能不會與'date_begin'在同一行。 – MT0

0
select 
    t.bonus_id, 
    t.bonus_date_begin, 
    t.service_id, 
    t.service_name, 
    t.service_date_begin 
from (
    select 
    b.bonus_id, 
    b.date_begin as bonus_date_begin, 
    s.service_id, 
    s.name as service_name, 
    s.date_begin as service_date_begin, 
    row_number() over (
     partition by b.bonus_id 
     order by s.date_begin desc, s.service_id desc 
    ) as rn 
    from avd_bonus b 
    left join avd_service s on b.bonus_id = s.bonus_id and s.date_begin <= b.date_begin 
) t 
where t.rn = 1; 
相關問題