如果仅其子记录符合某些条件,则内部联接并检索父记录

时间:2017-03-15 12:45:13

标签: sql oracle

表CP

CP_Name  CP_Number  CP_PK
-------  ---------  -----
AA             111    123
BB             222    124
CC             333    125
DD             444    126
EE             555    127
FF             666    128
GG             777    129

表PP

PP_Name  PP_Number  PP_Phase    PP_PK  Parent_PK
-------  ---------  ----------  -----  ---------
ABC          11111  Active        345        123
DEF          22222  Inactive      346        123
GHI          33333  Inactive      347        124
JKL          44444  Terminated    348        124
MNO          55555  TDR           349        126
PQR          66666  Active        350        126
STU          77777  Inactive      351        127
VWX          88888  Active        352        128
YX           99999  TDR           353        129
BCA          12121  Terminated    354        126

结果:

CP_Name  CP_Number  PP_Name  PP_Number  PP_Phase    CP_PK  Parent_PK
-------  ---------  -------  ---------  ----------  -----  ---------
AA             111  ABC          11111  Active        123        123
AA             111  DEF          22222  Inactive      123        123
DD             444  MNO          55555  TDR           126        126
DD             444  PQR          66666  Active        126        126
DD             444  BCA          12121  Terminated    126        126

我有两个与CP_PK = Parent_PK相关的表格。表PP是表CP的子项。

我正在尝试查找表CP至少有两个子行(可能超过两行)的情况,其中一个子项可能等于Inactive,{{1} }或Terminated然后另一个孩子可能等于Transferred to TPDActiveTDR ApprovedTDR Draft。我开始使用基于TDR Final的两个表格的内部联接,然后使用CP_PK = Parent_PKPP_Phase = 'xxx',但很快意识到这不起作用。有什么建议/想法吗?

3 个答案:

答案 0 :(得分:1)

试试这个

select * from (select Count(*) OVER (partition by CP.CP_PK) cnt, CP.* from CP              
                INNER JOIN PP  ON CP.CP_PK = PP.Parent_PK where some Condition1  or some condition2) a where a.cnt>1

答案 1 :(得分:1)

SELECT cp.*
FROM
  CP
  INNER JOIN
  (
    SELECT parent_pk
    FROM   PP
    GROUP BY parent_pk
    HAVING COUNT(
             CASE WHEN Parent_PK IN ( 'Inactive', 'Terminated', 'Transferred to TPD'
                  THEN 1 END
           ) >= 1
    AND    COUNT(
             CASE WHEN Parent_PK IN ( 'Active', 'TDR Approved', 'TDR Draft', 'TDR Final'
                  THEN 1 END
           ) >= 1
  ) pp
  ON ( cp.cp_pk = pp.parent_pk )

答案 2 :(得分:1)

这是Boneist在他/她的原始帖子下的第一篇评论中提到的。根据需要进行调整;这不完全是你需要的,但它应该足够接近,你应该能够自己修改它。

with
     cp ( cp_name, cp_number, cp_pk ) as (
       select 'AA', 111, 123 from dual union all
       select 'BB', 222, 124 from dual union all
       select 'CC', 333, 125 from dual union all
       select 'DD', 444, 126 from dual union all
       select 'EE', 555, 127 from dual union all
       select 'FF', 666, 128 from dual union all
       select 'GG', 777, 129 from dual
     ),
     pp ( pp_name, pp_number, pp_phase, pp_pk, parent_pk ) as (
       select 'ABC', 11111, 'Active'    , 345, 123 from dual union all
       select 'DEF', 22222, 'Inactive'  , 346, 123 from dual union all
       select 'GHI', 33333, 'Inactive'  , 347, 124 from dual union all
       select 'JKL', 44444, 'Terminated', 348, 124 from dual union all
       select 'MNO', 55555, 'TDR'       , 349, 126 from dual union all
       select 'PQR', 66666, 'Active'    , 350, 126 from dual union all
       select 'STU', 77777, 'Inactive'  , 351, 127 from dual union all
       select 'VWX', 88888, 'Active'    , 352, 128 from dual union all
       select 'YX' , 99999, 'TDR'       , 353, 129 from dual union all
       select 'BCA', 12121, 'Terminated', 354, 126 from dual
     )
select cp_pk, cp_name, cp_number, pp_pk, pp_name, pp_number, pp_phase
from   ( select cp_pk, cp_name, cp_number, pp_pk, pp_name, pp_number, pp_phase,
                count(case when pp_phase in ('Active', 'TDR')          then 1 end) 
                                                     over (partition by cp_pk) as flag_1,
                count(case when pp_phase in ('Inactive', 'Terminated') then 1 end) 
                                                     over (partition by cp_pk) as flag_2
         from   cp join pp on cp.cp_pk = pp.parent_pk
       )
where  flag_1 > 0 and flag_2 > 0
;

<强>输出

CP_PK CP_NAME  CP_NUMBER PP_PK PP_NAME  PP_NUMBER PP_PHASE
----- ------- ---------- ----- ------- ---------- ----------
  123 AA             111   346 DEF          22222 Inactive
  123 AA             111   345 ABC          11111 Active
  126 DD             444   350 PQR          66666 Active
  126 DD             444   354 BCA          12121 Terminated
  126 DD             444   349 MNO          55555 TDR

5 rows selected.