【问题标题】:Oracle SQL recursion to find first instance of non-null column valueOracle SQL递归查找非空列值的第一个实例
【发布时间】:2013-07-09 16:02:35
【问题描述】:

我会试着解释一下表格是如何布置的,这样我需要的东西可能会更清楚一点。

###############################################################
# cid # iid # child cid # child iid # target cid # target iid #
############################################################### 
# 112 # 1   # null      # null      # 116        # 1          #
# 112 # 2   # 112       # 1         # null       # null       #
# 112 # 3   # 112       # 1         # 116        # 2          #
# 112 # 4   # 112       # 1         # 100        # 3          #
# 112 # 101 # null      # null      # 116        # 101        #
# 112 # 102 # 112       # 101       # null       # null       #
# 112 # 103 # 112       # 101       # 116        # 102        #
# 112 # 201 # null      # null      # 116        # 201        #
# 112 # 202 # 112       # 201       # null       # null       #
# 112 # 203 # 112       # 201       # 116        # 202        #
# 112 # 301 # null      # null      # 116        # 301        #
# 112 # 302 # 112       # 301       # null       # null       #
# 112 # 302 # 112       # 301       # 116        # 302        #

上面是我试图从中获取数据的表格的简化表示。对不起,如果布局有点废话。这里的每一行都是一个对象。这些对象中的每一个都可以有子对象,例如,第一行没有子对象但链接到目标对象。第二行有一个子对象并且没有链接到目标对象,但是,它通过确实有目标对象的子 cid 和 iid 链接回第 1 行。第三行也链接到第一行,但它也有一个目标对象,所以我实际上不想回到第一行。

其他表

#########################################
# cid # iid # col1 # col2 # col3 # col4 #
#########################################
# 116 # 1   # a    # null # 16   # 1    #
# 116 # 2   # b    # 1    # 6    # null #
# 116 # 3   # n    # 1    # 11   # 2    #
# 116 # 101 # n    # 2    # 61   # 3    #
# 116 # 102 # b    # null # 161  # 101  #
# 116 # 201 # a    # 33   # 312  # 116  # 
# 116 # 202 # a    # 33   # 312  # 116  # 
# 116 # 301 # s    # 56   # 1321 # 33   #
# 116 # 302 # r    # 6    # 22   # 12   #

结果表

###########################################################################################
# cid # iid # child cid # child iid # target cid # target iid # col1 # col2 # col3 # col4 #
###########################################################################################
# 112 # 1   # null      # null      # 116        # 1          # a    # null # 16   # 1    #
# 112 # 2   # 112       # 1         # null       # null       # a    # null # 16   # 1    #
# 112 # 3   # 112       # 1         # 116        # 2          # b    # 1    # 6    # null #
# 112 # 4   # 112       # 1         # 100        # 3          # n    # 1    # 11   # 2    #
# 112 # 101 # null      # null      # 116        # 101        # n    # 2    # 61   # 3    #
# 112 # 102 # 112       # 101       # null       # null       # n    # 2    # 61   # 3    #
# 112 # 103 # 112       # 101       # 116        # 102        # b    # null # 161  # 101  #
# 112 # 201 # null      # null      # 116        # 201        # a    # 33   # 312  # 116  #
# 112 # 202 # 112       # 201       # null       # null       # a    # 33   # 312  # 116  #
# 112 # 203 # 112       # 201       # 116        # 202        # a    # 33   # 312  # 116  # 
# 112 # 301 # null      # null      # 116        # 301        # s    # 56   # 1321 # 33   #
# 112 # 302 # 112       # 301       # null       # null       # s    # 56   # 1321 # 33   #
# 112 # 302 # 112       # 301       # 116        # 302        # r    # 6    # 22   # 12   #

[澄清一下,在第一个表中,目标 cid 和 iid 与链接到它的另一个表中的 cid 和 iid 相关。]

基本上我需要的是递归地遍历表,直到行具有目标对象引用。

如果一行同时具有子 c/i id 和目标 c/i id,我只想要目标 c/i id。

谁能指出我正确的方向?

我正在慢慢阅读 http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm 但我发现它有点令人困惑。我不会完全是更简单的 SQL 查询方面的专家,所以递归现在有点过头了。

谢谢

编辑:添加其他表格和结果的示例

【问题讨论】:

  • 此数据的预期结果是什么?
  • 基本上,我正在尝试将另一个表链接到这个表。这个想法是目标 id 应该与另一个表的匹配。我需要上表的每一行都引用一个目标 iid,这样我就可以将另一个表中的相关数据链接到它。
  • 显示两张表+数据和预期结果。
  • 这不是 DB2 问题,标记错误。
  • 添加表并删除 DB2 标记

标签: sql oracle recursion hierarchical-data


【解决方案1】:

我不知道你到底需要什么,但是 你可以从 tihs 声明开始

select cid, iid, level, connect_by_root(target_cid), connect_by_root(target_iid)
from tab
connect by    prior cid = child_cid
          AND prior iid = child_iid
          AND target_cid is null          
; 

然后过滤你需要的条目

select *
from 
(
select cid, iid, level, connect_by_root(target_cid) as target_cid, connect_by_root(target_iid) as target_iid
from tab
connect by    prior cid = child_cid
          AND prior iid = child_iid
          AND target_cid is null          
)
where target_cid is not null
;          

    CID IID TARGET_CID TARGET_IID
    ++++++++++++++++++++++++++++++
    112 1     116         1
    112 2     116         1
    112 3     116         2
    112 4     100         3
    112 101   116         101
    112 102   116         101
    112 103   116         102
    112 201   116         201
    112 202   116         201
    112 203   116         202
    112 301   116         301
    112 302   116         301
    112 302   116         302

【讨论】:

  • 很好的起点,帮助我解决了类似的问题。据我所知,不是过滤(嵌套查询和where target_cid is not null),而是可以在没有嵌套查询的情况下编写start with target_cid is not null connect by ...,以仅获得target_cid 的非空结果(但我只测试了它在非常有限的数据集上)
猜你喜欢
  • 2011-01-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-03
  • 1970-01-01
  • 2013-09-15
  • 2012-08-29
相关资源
最近更新 更多