问题描述
你好,我有这个问题,我到目前为止还没有解决,尽管我怀疑它应该使用分层查询。
我在保存和共享的LiveSQL脚本中包含了示例/测试数据,为方便起见,它包括假设查询将为每行返回的所需结果,在列expected_master_group2中。
确定结果的要求:
我们有这个表,每一行都有group1和group2值 (从不空或空)。
我们希望使用sql为他们中的每一个找到group1的 “主” (因为缺少更好的单词) group2值,考虑到:
1-对于给定的group1值,我们可以有一个或多个group2值。
2-对于给定的group2值,我们可以有一个或多个group1值。
3-如果group1具有单个group2,并且该group2也具有此单个group1相关,则我们的主group2将是group2。
4-如果group1具有许多group2,但是这些group2中的每一个都没有链接到任何其他group1,则group1的min(group2) 将是主group2。
5-如果一个group1有一个或多个group2,如果这些group2中的任何一个链接到一个或多个其他group1,那么我们需要找到那些其他链接的group1,找到它们是否本身链接到我们已经见过的不同group2,等等,在找到所有group2之前,我们可能会与给定的group1联系起来。然后,主group2将是我们通过遍历所有这些关系创建的列表中的min(group2)。
例如,要确定对于具有group1 = 129653的行,我要构建的查询 (并放入expected_master_group2) 要检索的预期结果为 “4190412”:
-具有group1 = 129653的两个行都具有group2 = '4190414 '。
-group2 = '4190414 '还与具有group1 = 129654的行有关。
-有2行具有group1 = 129654,一行具有group2 = '4190414 '(我们已经 “看到” 了),一行具有group2 = '4190413'。
-group2 = '4190413 '与3行相关,分别具有group1 = 129653 (已经看到) 、129654 (已经看到) 和129669。
-group1 = 129669与group2的 “4190413” (已经看到) 和 “4190412” 有关
-group2 = “4190412” 与group1的129668,129670和129669有关 (已经看到)
-group1s 129668,129670只有group2 = '4190412 ',我们已经完成了遍历关系。
-我们已经看到了group2的 “4190414”,“4190413” 和 “4190412”。
-Group2'4190412 '是我们见过的所有group2s中最小的,这是我要寻找的结果,对于具有group1 = 129653的行。
我希望我的解释足够清楚和透彻。
谢谢。
我在保存和共享的LiveSQL脚本中包含了示例/测试数据,为方便起见,它包括假设查询将为每行返回的所需结果,在列expected_master_group2中。
确定结果的要求:
我们有这个表,每一行都有group1和group2值 (从不空或空)。
我们希望使用sql为他们中的每一个找到group1的 “主” (因为缺少更好的单词) group2值,考虑到:
1-对于给定的group1值,我们可以有一个或多个group2值。
2-对于给定的group2值,我们可以有一个或多个group1值。
3-如果group1具有单个group2,并且该group2也具有此单个group1相关,则我们的主group2将是group2。
4-如果group1具有许多group2,但是这些group2中的每一个都没有链接到任何其他group1,则group1的min(group2) 将是主group2。
5-如果一个group1有一个或多个group2,如果这些group2中的任何一个链接到一个或多个其他group1,那么我们需要找到那些其他链接的group1,找到它们是否本身链接到我们已经见过的不同group2,等等,在找到所有group2之前,我们可能会与给定的group1联系起来。然后,主group2将是我们通过遍历所有这些关系创建的列表中的min(group2)。
例如,要确定对于具有group1 = 129653的行,我要构建的查询 (并放入expected_master_group2) 要检索的预期结果为 “4190412”:
-具有group1 = 129653的两个行都具有group2 = '4190414 '。
-group2 = '4190414 '还与具有group1 = 129654的行有关。
-有2行具有group1 = 129654,一行具有group2 = '4190414 '(我们已经 “看到” 了),一行具有group2 = '4190413'。
-group2 = '4190413 '与3行相关,分别具有group1 = 129653 (已经看到) 、129654 (已经看到) 和129669。
-group1 = 129669与group2的 “4190413” (已经看到) 和 “4190412” 有关
-group2 = “4190412” 与group1的129668,129670和129669有关 (已经看到)
-group1s 129668,129670只有group2 = '4190412 ',我们已经完成了遍历关系。
-我们已经看到了group2的 “4190414”,“4190413” 和 “4190412”。
-Group2'4190412 '是我们见过的所有group2s中最小的,这是我要寻找的结果,对于具有group1 = 129653的行。
我希望我的解释足够清楚和透彻。
谢谢。
专家解答
是的。你可以使用递归与沿着层次结构走。搜索与当前中相应值匹配的下一行的group1或group2值。
group2的几个值有很多行。因此,如果您所做的只是上面的检查,您将继续回到相同的g2值。这意味着一遍又一遍地重新审视g1值...这会爆炸您的层次结构,使查询取f o r e v e r。
您可以通过跟踪您访问的先前g1/g2值来避免这种情况。如果下一行的任何一个值与源的值匹配,请不要返回。
把它们放在一起,你会得到:
HT对Kim Berg Hansen的递归子查询图遍历是这个答案的灵感来源:https://www.kibeha.dk/2013/01/recursive-subquery-graph-traversing.html
group2的几个值有很多行。因此,如果您所做的只是上面的检查,您将继续回到相同的g2值。这意味着一遍又一遍地重新审视g1值...这会爆炸您的层次结构,使查询取f o r e v e r。
您可以通过跟踪您访问的先前g1/g2值来避免这种情况。如果下一行的任何一个值与源的值匹配,请不要返回。
把它们放在一起,你会得到:
with s_data as ( select distinct * from sample_data ), tree ( g1, g2, g1_orig, g2_orig, rt, expect ) as ( select group1, group2, 0, '0', group1, expected_master_group2 from s_data union all select s.group1, s.group2, t.g1, t.g2, t.rt , expect from tree t join s_data s on ( ( t.g1 = s.group1 ) or ( t.g2 = s.group2 ) ) and ( t.g1_orig <> s.group1 and t.g2_orig <> s.group2 ) ) select rt, expect, min ( g2 ), case when expect = min ( g2 ) then 'SUCCESS!' else 'FAIL :(' end is_correct from tree group by rt, expect; RT EXPECT MIN(G2) IS_CORRECT 129654 4190412 4190412 SUCCESS! 129659 4188693 4188693 SUCCESS! 129668 4190412 4190412 SUCCESS! 129676 4188693 4188693 SUCCESS! 129670 4190412 4190412 SUCCESS! 129660 4188693 4188693 SUCCESS! 129674 4188693 4188693 SUCCESS! 129653 4190412 4190412 SUCCESS! 129658 4188693 4188693 SUCCESS! 129655 4188693 4188693 SUCCESS! 129656 4188693 4188693 SUCCESS! 129678 4188693 4188693 SUCCESS! 129671 4188693 4188693 SUCCESS! 129672 4188693 4188693 SUCCESS! 129673 4188693 4188693 SUCCESS! 129669 4190412 4190412 SUCCESS! 129657 4188693 4188693 SUCCESS! 129677 4188693 4188693 SUCCESS! 129679 11219712 11219712 SUCCESS! 129675 4188693 4188693 SUCCESS!复制
HT对Kim Berg Hansen的递归子查询图遍历是这个答案的灵感来源:https://www.kibeha.dk/2013/01/recursive-subquery-graph-traversing.html
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。
评论
相关阅读
Oracle RAC 一键安装翻车?手把手教你如何排错!
Lucifer三思而后行
595次阅读
2025-04-15 17:24:06
【纯干货】Oracle 19C RU 19.27 发布,如何快速升级和安装?
Lucifer三思而后行
564次阅读
2025-04-18 14:18:38
XTTS跨版本迁移升级方案(11g to 19c RAC for Linux)
zwtian
482次阅读
2025-04-08 09:12:48
Oracle数据库一键巡检并生成HTML结果,免费脚本速来下载!
陈举超
473次阅读
2025-04-20 10:07:02
【ORACLE】记录一些ORACLE的merge into语句的BUG
DarkAthena
457次阅读
2025-04-22 00:20:37
【ORACLE】你以为的真的是你以为的么?--ORA-38104: Columns referenced in the ON Clause cannot be updated
DarkAthena
431次阅读
2025-04-22 00:13:51
Oracle 19c RAC更换IP实战,运维必看!
szrsu
430次阅读
2025-04-08 23:57:08
【活动】分享你的压箱底干货文档,三篇解锁进阶奖励!
墨天轮编辑部
415次阅读
2025-04-17 17:02:24
火焰图--分析复杂SQL执行计划的利器
听见风的声音
359次阅读
2025-04-17 09:30:30
3月“墨力原创作者计划”获奖名单公布
墨天轮编辑部
357次阅读
2025-04-15 14:48:05