2012-06-26 115 views
0
TABLEA 
LOGIN_ID ,COL1,COL2 

TABLEB 
LOGIN_ID, RESIGN_DATE, LAST_DATE, STATUS 

我想從TABLEA的Oracle SQL聯接查詢

選擇特定的LOGIN_ID LOGIN_ID,resign_date和LAST_DATE LOGIN_ID是TABLEA和TABLEB之間的聯繫。在TABLEB中,對於相同的login_id可以有多個記錄。我想選擇將滿足以下條件的resign_date和last_date。

1)if status is null for at least one of them 
    it should identify that entry whose status is null 
    System populate the resign_date and last_date of this entry 
2)if status is ‘Y’ for all of them 
     resign_date = ’12/31/2050’ 
     last_date = ’12/31/2050’ 
3)If no entry in TABLEB 
    resign_date = null 
    last_date = null 

如何編寫一個oracle sql查詢?

+0

:系統將如何填充空條目的日期...它會是什麼日期?我在詢問第一個條件 –

+0

如果多於一個的TABLEB行的狀態爲null會怎麼樣? –

+0

@GauravSoni在這種情況下,我應該得到狀態爲空的條目的resign_date和last_date .. – Andromeda

回答

0

如果您正在使用Oracle 9i,相對2或更高版本,這應該工作...

with c as (select * from tableb where status is null) 

select * 
from tablea 
left join 
(
     select login_id, resign_date, last_date from c 
     union 
     select login_id, '12/31/2050', '12/31/2050' from tableb 
       where login_id not in (select login_id from c) 
) d on tablea.login_Id = d.login_Id 

我假設狀態Y或TableB中零

0

您可以使用analytic functions要做到這一點,其優點是隻能擊中每張桌子一次。

select distinct a.login_id, 
    case when b.login_id is null then null 
     when first_value(b.status) over (partition by b.login_id 
      order by b.status nulls first) is null then b.resign_date 
     when first_value(b.status) over (partition by b.login_id 
      order by b.status nulls first) = 'Y' then date '2050-12-31' 
    end as resign_date, 
    case when b.login_id is null then null 
     when first_value(b.status) over (partition by b.login_id 
      order by b.status nulls first) is null then b.last_date 
     when first_value(b.status) over (partition by b.login_id 
      order by b.status nulls first) = 'Y' then date '2050-12-31' 
    end as last_date 
from tablea a 
left join tableb b on b.login_id = a.login_id 
order by a.login_id; 

相關部分是case說法 - 有兩個,但它們是相同的,除了這是從TABLEB返回列。該案有三個條款:

when b.login_id is null then null 

如果在TABLEB沒有匹配的記錄,因爲外部的,參加B.LOGIN_ID將是無效的;這符合你的第三個標準。

when first_value(b.status) over (partition by b.login_id 
    order by b.status nulls first) is null then b.resign_date 

first_value()函數返回「最低」的狀態值,nulls first意味着,如果有任何的匹配TABLEB記錄有一個空的狀態,這就是將第一次看到。所以這符合你的第一個標準,並且對該空狀態行使用TABLEB.RESIGN_DATE

when first_value(b.status) over (partition by b.login_id 
    order by b.status nulls first) = 'Y' then date '2050-12-31' 

同以前的條款,但如果第一個值是Y,那就不會有任何空,因爲nulls first的這個時候再次。 (這是假設狀態只能是null或'Y',你的問題暗示 - 如果有其他狀態,那麼行爲沒有在你的標準中指定)。因此,如果TABLEB中的所有匹配行的狀態爲Y,則會使用與您的第二個條件相匹配的固定日期值。

請注意,我在這裏使用了date literal;如果你願意,你可以使用to_date('12/31/2050', 'MM/DD/YYYY'),但不要使用隱式轉換,並假定將使用特定的日期掩碼。