Oracle SQL连接查询

Oracle SQL连接查询,sql,oracle,join,Sql,Oracle,Join,我想从表a中为特定登录id选择登录id、辞职日期和最后日期 登录ID是TABLEA和TABLEB之间的链接。在表B中,同一登录id可以有多条记录。我想选择辞职日期和最后日期,这将满足以下条件 TABLEA LOGIN_ID ,COL1,COL2 TABLEB LOGIN_ID, RESIGN_DATE, LAST_DATE, STATUS 如何为此编写oracle sql查询 如果您使用的是Oracle 9i rel 2或更高版本,这应该可以 1)if status is null for

我想从表a中为特定登录id选择登录id、辞职日期和最后日期

登录ID是TABLEA和TABLEB之间的链接。在表B中,同一登录id可以有多条记录。我想选择辞职日期和最后日期,这将满足以下条件

TABLEA
LOGIN_ID ,COL1,COL2

TABLEB
LOGIN_ID, RESIGN_DATE, LAST_DATE, STATUS

如何为此编写oracle sql查询

如果您使用的是Oracle 9i rel 2或更高版本,这应该可以

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
我假设tableB中的status为Y或null,您可以使用它来执行此操作,它的优点是每个表只命中一次

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
相关部分是
case
语句-有两个,但它们是相同的,除了从
TABLEB
返回的列之外。本案有三项条款:

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;
如果
表B
中没有匹配的记录,因为外部连接
B。登录ID
将为空;这符合您的第三个标准

when b.login_id is null then null
first\u value()
函数返回“最低”状态值,
null first
意味着如果任何匹配的
TABLEB
记录的状态为null,则首先会看到它。因此,这符合您的第一个条件,并使用
TABLEB.demist\u DATE
作为空状态行

when first_value(b.status) over (partition by b.login_id
    order by b.status nulls first) is null then b.resign_date
与上一个子句相同,但这一次如果第一个值是
Y
,那么就不能有任何空值,因为
nulls first
。(这是假设状态只能是
null
或'Y',这是您的问题所暗示的-如果存在任何其他状态,则您的标准中不会指定该行为)。因此,如果
表b
中的所有匹配行的状态均为
Y
,则将使用与第二个条件匹配的固定日期值

when b.login_id is null then null

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

:系统将如何填充空输入的日期…将是什么日期?我问的是第一个条件,如果有多个TABLEB行的状态为空怎么办?@GauravSoni在这种情况下,我应该得到状态为空的条目的辞职日期和最后日期。@TonyAndrews只有一行的状态为空。。我忘了提它了。@Ollie我试着用left-join写它……我没能让它工作。。