Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何使用SQL Oracle数据库返回特定的父/子结果_Sql_Oracle - Fatal编程技术网

如何使用SQL Oracle数据库返回特定的父/子结果

如何使用SQL Oracle数据库返回特定的父/子结果,sql,oracle,Sql,Oracle,这是我的第一个问题,因此,对于任何礼仪错误,我深表歉意 我有三个相关的表格 ID-此表提供所有记录的可见ID 父\子\关系-将父记录与其子记录链接起来 详细信息-提供所有记录的详细信息 样本数据 Table ID PARENT_CHILD_RELATIONSHIP DETAILS Columns KEY|PROPER_ID PARENT_KEY|CHILD_KEY KEY|FIELD 1|P1

这是我的第一个问题,因此,对于任何礼仪错误,我深表歉意

我有三个相关的表格

ID-此表提供所有记录的可见ID
父\子\关系-将父记录与其子记录链接起来
详细信息-提供所有记录的详细信息

样本数据

Table    ID                  PARENT_CHILD_RELATIONSHIP  DETAILS
Columns  KEY|PROPER_ID       PARENT_KEY|CHILD_KEY       KEY|FIELD
         1|P1                1|NULL                     5|A
         2|P2                2|5                        5|C
         3|P3                2|6                        6|A
         4|P4                3|7                        6|D
         5|C1                4|8                        7|B
         6|C2                4|9                        7|C 
         7|C3                                           8|A
         8|C4                                           8|C
         9|C5                                           9|B
                                                        9|C
以下是我的查询的简化示例:

SELECT DISTINCT I.PROPER_ID, CHILD_ID_A.PROPER_ID, CHILD_ID_B.PROPER_ID

FROM ID I                   

LEFT OUTER JOIN PARENT_CHILD_RELATIONSHIP PCR_A ON PCR_A.PARENT_KEY = I.KEY
LEFT OUTER JOIN DETAILS D_A ON D_A.KEY = PCR_A.CHILD_KEY
AND D_A.FIELD = ('A')                
LEFT OUTER JOIN ID CHILD_ID_A ON CHILD_ID_A.KEY = DETAILS_A.KEY

LEFT OUTER JOIN PARENT_CHILD_RELATIONSHIP PCR_B ON PCR_B.PARENT_KEY = I.KEY
LEFT OUTER JOIN DETAILS D_B ON D_B.KEY = PCR_B.CHILD_KEY
AND D_B.FIELD = ('B')                
LEFT OUTER JOIN ID CHILD_ID_B ON CHILD_ID_B.KEY = DETAILS_B.KEY

WHERE I.PROPER_ID IN('1', '2', '3', '4')
我想要的是返回第1列中(父)正确的\u ID为1,2,3,4的所有记录。然后,在第2列中,我想返回子记录的正确ID,如果该记录在Details表中有“A”。对于第3列,我希望执行与第2列相同的操作,但在细节表中有一个带“B”的子记录

我可以看到四种可能的情况:
1.详细信息表中有0个带“A”或“B”的子记录-在这种情况下,我希望返回一行,其中只包含正确的父级ID,并在随后的两列中保留空格。
2.明细表中有一个或多个带有“A”的子记录-在这种情况下,我希望返回的行数与子记录的行数相同。
3.如上所述,但在详细信息表中只有“B”。
4.同时存在“A”和“B”子记录-在本例中,如果每个子记录都有一个,我希望在同一行上重新运行所有数据

电流输出

I.PROPER_ID | CHILD_ID_A.PROPER_ID | CHILD_ID_B.PROPER_ID
P1          | NULL                 | NULL
P2          | C1                   | NULL
P2          | C2                   | NULL
P2          | NULL                 | NULL
P3          | NULL                 | C3
P3          | NULL                 | NULL
P4          | C4                   | C5
P4          | C4                   | NULL  
P4          | NULL                 | C5      
P4          | NULL                 | NULL
我想要的输出:

I.PROPER_ID | CHILD_ID_A.PROPER_ID | CHILD_ID_B.PROPER_ID
P1          | NULL                 | NULL
P2          | C1                   | NULL
P2          | C2                   | NULL
P3          | NULL                 | C3
P4          | C4                   | C5
这可能吗?我尝试了许多不同的变体,并尝试搜索其他示例,但还没有找到解决方案


任何帮助都将不胜感激

我认为您可以使用pivot(11g或更高版本;在早期版本中可以使用手动版本),例如:

select * from (
  select p.proper_id as parent_id, c.proper_id as child_id, d.field,
    row_number() over (partition by p.key, d.field order by c.key) as rn
  from id p
  join parent_child_relationship pcr on pcr.parent_key = p.key
  left join id c on c.key = pcr.child_key
  left join details d on d.key = c.key and d.field in ('A', 'B')
  where p.proper_id in ('P1', 'P2', 'P3', 'P4')
)
pivot (max(child_id) as child for (field) in ('A' as a, 'B' as b))
内部查询中的
row\u number()
允许它为P2保留两个单独的行。如果父母有超过a和B的记录,他们会配对,这可能是你想要的,也可能不是你想要的,但不清楚这是否会发生

使用您的样本数据作为CTE:

with ID (KEY, PROPER_ID) as (
  select 1, 'P1' from dual
  union all select 2, 'P2' from dual
  union all select 3, 'P3' from dual
  union all select 4, 'P4' from dual
  union all select 5, 'C1' from dual
  union all select 6, 'C2' from dual
  union all select 7, 'C3' from dual
  union all select 8, 'C4' from dual
  union all select 9, 'C5' from dual
), PARENT_CHILD_RELATIONSHIP (PARENT_KEY, CHILD_KEY) as (
  select 1, null from dual
  union all select 2, 5 from dual
  union all select 2, 6 from dual
  union all select 3, 7 from dual
  union all select 4, 8 from dual
  union all select 4, 9 from dual
), DETAILS (KEY, FIELD) as (
  select 5, 'A' from dual
  union all select 6, 'A' from dual
  union all select 7, 'B' from dual
  union all select 8, 'A' from dual
  union all select 9, 'B' from dual
)
select parent_id, a_child as child_a_id, b_child as child_b_id
from (
  select p.proper_id as parent_id, c.proper_id as child_id, d.field,
    row_number() over (partition by p.key, d.field order by c.key) as rn
  from id p
  join parent_child_relationship pcr on pcr.parent_key = p.key
  left join id c on c.key = pcr.child_key
  left join details d on d.key = c.key and d.field in ('A', 'B')
  where p.proper_id in ('P1', 'P2', 'P3', 'P4')
)
pivot (max(child_id) as child for (field) in ('A' as a, 'B' as b))
order by 1, 2, 3;
这将产生:

PARENT_ID CHILD_A_ID CHILD_B_ID
--------- ---------- ----------
P1                             
P2        C1                   
P2        C2                   
P3                   C3        
P4        C4         C5        
如果您使用的早期版本不支持
pivot
,则可以更明确地执行相同的操作:

select parent_id,
  max(case when field = 'A' then child_id end) as child_a_id,
  max(case when field = 'B' then child_id end) as child_b_id
from (
  select p.proper_id as parent_id, c.proper_id as child_id, d.field,
    row_number() over (partition by p.key, d.field order by c.key) as rn
  from id p
  join parent_child_relationship pcr on pcr.parent_key = p.key
  left join id c on c.key = pcr.child_key
  left join details d on d.key = c.key and d.field in ('A', 'B')
  where p.proper_id in ('P1', 'P2', 'P3', 'P4')
)
group by parent_id, rn
order by 1, 2, 3;

在你的问题中加入一些样本数据和预期结果会有帮助;以及您当前查询的问题。谢谢@alex poole-我已经添加了这些-希望不要太复杂。ID.property\u ID与ID.KEY相同还是其他?您发布的查询也没有一致地使用别名,这有点令人困惑。父母/子女关系是否只有一个层次——没有孙子女?(不确定为什么您有一个单独的父/子表,而不仅仅是ID中的父列。)它们是两个不同的字段,正确的ID仅存在于ID表中-也许值得我在示例数据中澄清,以便它显示正确的表内容?只有一级父/子。是,请确保查询和当前输出与该样本数据匹配。真的在寻找,因为我不确定我是否理解您试图做的事情的描述。非常感谢您的回答,如果我运行9i,您对pivot的手动版本有什么建议吗?@AlexJ-我在最后添加了手动版本。不管怎样,
pivot
语法在引擎盖下做同样的事情。我会将此标记为已回答,非常感谢您的帮助。如果你有机会,你能编辑添加where语句(where I.property_ID IN('1','2','3','4')吗?好吧,忘了,虽然这些不是你的数据中的值*8-),我只是猜测,但你实际上可能只想基于所有的
父项
值,
id
prc
之间的内部连接到底做了什么-取决于您的值列表是否应该涵盖所有这些值,您可能使用了其中的一小部分。要点很好:)再次感谢您的帮助!我会有一个更好的主意,下次如何提出问题,真的很有用的建议。