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

您可以使用分析函数来执行此操作,其优点是只需访问每个表一次。

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具有 status Y,这将使用与您的第二个条件匹配的固定日期值。

请注意,我在这里使用了日期文字;如果您愿意,您可以使用to_date('12/31/2050', 'MM/DD/YYYY'),但不要使用隐式转换并假设特定的日期掩码将起作用。

于 2012-06-26T18:15:44.183 回答
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

我假设 tableB 中的状态是 Y 或 null

于 2012-06-26T11:40:56.150 回答