外链强制链

时间:2019-04-11 10:18:06

标签: sql oracle outer-join

想象一下我有这个数据

人员->地址更改->地址更改原因

我想要所有人的细节 我也想知道他们是否因为火灾而改变了住址。因此,我不想知道原因是什么,但是如果他们仅出于一个原因而更改了地址。

每个人可能有多个地址更改原因

所以我有

SELECT people.*
CASE WHEN add_change.reason_id is not NULL THEN
  'Y'
 ELSE 
  'N'
 END as been_fire
from people
left outer join add_change ON  person.id = add_change.person
left outer join add_change_reason ON add_change.reason_id = add_change_reason.id  AND add_change_reason.text = 'FIRE'

但是如果每人有很多地址更改,这将返回每人多行。

我不能只使用

left outer join add_change ON add_change.person = person.id AND add_change.reason_id = 5

这不是固定数据。

2 个答案:

答案 0 :(得分:1)

使用exists

SELECT p.*,
       (CASE WHEN EXISTS (SELECT 1
                          FROM add_change ac JOIN
                               add_change_reason acr
                               ON ac.reason_id = acr.id 
NVL(address_change.reason,'N')
                          WHERE p.id = ac.person AND
                                acr.text = 'FIRE'
                         )
             THEN 'Y' ELSE 'N'
        END) as has_fire_address_change
from people p;

请注意,这会将标志更改为'Y''N',这是对问题的描述表明您想要的。

答案 1 :(得分:1)

您可以对派生表进行左联接,该派生表仅返回确实具有更改原因“ FIRE”的人员ID:

SELECT p.*
       CASE WHEN cr.person IS NOT NULL THEN 'Y' ELSE 'N' END as been_fire
from people
  left join (
    select ac.person
    from add_change ac
    where exists (select *
                  from add_change_reason acr 
                  where acr.id  = ac.reason_id 
                    AND acr.text = 'FIRE')
  ) cr on cr.person = p.id