0
TABLEA
LOGIN_ID ,COL1,COL2

TABLEB
LOGIN_ID, RESIGN_DATE, LAST_DATE, STATUS

TABLEA から特定の 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クエリを作成する方法は??

4

2 に答える 2

0

Oracle 9i rel 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

テーブルBのステータスはYまたはnullのいずれかであると想定しています

于 2012-06-26T11:40:56.150 に答える
0

分析関数を使用してこれを行うことができます。これには、各テーブルに 1 回しかヒットしないという利点があります。

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ステートメントです。2 つありますが、どちらの列が から返されるかを除けば同じTABLEBです。ケースには次の 3 つの条項があります。

when b.login_id is null then null

に一致するレコードがない場合TABLEB、外部結合B.LOGIN_IDにより null になります。これは 3 番目の条件に一致します。

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レコードのいずれかが null ステータスである場合、それが最初に表示されることを意味します。したがって、これは最初の基準に一致しTABLEB.RESIGN_DATE、その null ステータス行を使用します。

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

前の句と同じですが、今回は最初の値が である場合Y、再度のために null は存在できませんnulls first。(これは、ステータスが「Y」または「Y」にしかならないことを前提としています。これはnull、質問が意味することです。他のステータスがある場合、動作は基準で指定されていません)。したがって、一致するすべての行TABLEBが statusYである場合、2 番目の条件に一致する固定の日付値が使用されます。

ここでは日付リテラルを使用していることに注意してください。必要に応じて を使用できますがto_date('12/31/2050', 'MM/DD/YYYY')、暗黙的な変換を使用せず、特定の日付マスクが使用されると想定してください。

于 2012-06-26T18:15:44.183 に答える