如何在Oracle

时间:2016-02-19 14:07:10

标签: oracle plsql

如何编写循环执行以下任务的查询:  (代替个别结果的id)

    SELECT * From Table where id= 24
    Id | next_to_check  |  next_to_check_2
     24|    34,23       | 4

然后我们检查我们展示的手段34,23,4

    SELECT * From tablle where id = 34
    SELECT * From tablle where id = 23
    SELECT * From tablle where id = 4

然后用结果替换结果34,23,4然后用结果替换结果并且更深入

24-> 34,23,4
34-> which results in a
23-> which results in a
4-> is as a result of

结果如何 - >结果等等...

当我手动执行时,它看起来像这样:

enter image description here

1 个答案:

答案 0 :(得分:0)

如果表格已正确规范化,查询将非常简单 正如评论中所提到的,有两个问题:

  • next_to_checknext_to_check2是两列,用于存储相同的值
  • 两列都包含以逗号分隔的值列表,而不是单个值

表格应如下所示:

SELECT * From Table where id= 24
    Id | next_to_check  | 
     24|    34          | 
     24|    23          |
     24|    4           |

其中next_to_check列的类型必须与id列相同,以避免不必要的投射。

对于上表,查询可能只是:

SELECT *
FROM "TABLE"
start with id = 24
connect by id = prior next_to_check;

如果表格无法规范化,那么您可以使用如下查询“即时”规范化数据:

WITH normalized_data As (
    SELECT id, trim(regexp_substr(next_to_check, '[^,]+', 1, LEVEL)) next_to_check
    FROM "TABLE"
    CONNECT BY LEVEL <= regexp_count(next_to_check, ',')+1  
    UNION ALL
    SELECT id, trim(regexp_substr(next_to_check_2, '[^,]+', 1, LEVEL)) next_to_check
    FROM "TABLE"
    CONNECT BY LEVEL <= regexp_count(next_to_check_2, ',')+1 
)
SELECT * FROM normalized_data

然后将第一个查询粘贴到上面的查询:

WITH normalized_data As (
    SELECT id, trim(regexp_substr(next_to_check, '[^,]+', 1, LEVEL)) next_to_check
    FROM "TABLE"
    CONNECT BY LEVEL <= regexp_count(next_to_check, ',')+1  
    UNION ALL
    SELECT id, trim(regexp_substr(next_to_check_2, '[^,]+', 1, LEVEL)) next_to_check
    FROM "TABLE"
    CONNECT BY LEVEL <= regexp_count(next_to_check_2, ',')+1 
)
SELECT * FROM normalized_data
start with id = 24
connect by id = prior next_to_check;

但是这种“解决方法”的表现会很差,它可能适用于100或1000条记录,但需要花费数年时间才能找到更大的表格。