【问题标题】:Recursing through heirarchy in a dataset [duplicate]通过数据集中的层次结构递归[重复]
【发布时间】:2020-06-29 12:59:33
【问题描述】:

假设我有一个具有以下结构的数据库表

表格中有三列 - case iddependent case id(s)deployment status 的案例 ID。

我想使用下面编写的 SQL 查询查询从属案例 ID 列表中的案例 ID。

select distinct dep_case_id from tbl_name where case_id = 1

根据上面的例子,1 依赖于2。反过来2 依赖于3, 4, 5。并且,3 依赖于4,依此类推。我想遍历直到与案例 id 1 相关的链结束(即)dep_case_id 必须变为 0。

python sn-p(如下所示)正在构建列表列表。我的 SQL 查询只需要 1 个参数,并且列表列表不满足该条件。结果它失败了,下面提到的结果。

import pyodbc    
cms_id_list = [1]
for i in cms_id_list:
        cursor.execute('select distinct dep_cms_id from bfs_Test where cms_id = ?', i)
        ids = cursor.fetchall()
        print(ids)
        first_tuple = [a_tuple[0] for a_tuple in ids]
        cms_id_list.append(first_tuple)
        print(cms_id_list) 

输出

[(2, )] #first query result using case id 1...a tuple result
[1, [2]] #cms_id_list after 2 got appended to the list.
[(3, ), (4, )] #second query result using case id 2 (obtained in previous iteration...a tuple result)
[1, [2], [3, 4]] #cms_id_list after 3,4 got appended to the list.

Traceback (most recent call last):
  File "C:\Users\Kris\eclipse-workspace\Utilities\Windows\recursion.py", line 22, in <module>
    cursor.execute('select distinct dep_cms_id from bfs_Test where cms_id = ?', i)
pyodbc.ProgrammingError: ('The SQL contains 1 parameter markers, but 2 parameters were supplied', 'HY000')

预期的输出是cms_id_list = [1, 2, 3, 4, 5]

我想要的只是将dep_case_ids 存储到一个扁平化cms_id_list。我写的代码不起作用而且是错误的,因为会发生列表项重复。

我在某处读过 BFS 算法非常适合这种情况。我不知道如何实现它。这就是我实现这个基本代码 sn-p 的原因。

我愿意修改和改进代码。

【问题讨论】:

  • 这与算法无关。代码有错误。 1)它将单个值和元组存储在一个容器中,这意味着您必须检查您正在阅读的内容。那很糟。 2)它在迭代时修改列表。您最终可能会两次读取相同的值,或者错过一个值。这也是非常低效的。 SQL 是一种面向集合的语言,它不需要循环。如果要检索分层数据,请使用 single 递归 CTE 检索从根一直到分支的所有行
  • BTW 递归 CTE 是大多数数据库中可用的标准 SQL 功能,包括 MySQL 8+
  • @PanagiotisKanavos 我已经根据您的建议回答了我自己的问题。谢谢你的建议:)

标签: python sql-server python-3.x tsql hierarchical-data


【解决方案1】:

我已经基于@Panagiontis Kanavos 实现了 SQL CTE。

这是查询。

with qcte (cms_id, dep_cms_id, [Level])
    as
    (
        select cms_id, dep_cms_id, 1 from bfs_Test where cms_id = 1

        union all

        select bfs_Test.cms_id, bfs_Test.dep_cms_id, qcte.[Level] + 1 from bfs_Test join qcte on bfs_Test.cms_id = qcte.dep_cms_id
    )
    select distinct * from qcte

它已经奏效了。现在我可以看到树的层次结构了。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-11-22
    • 2017-02-04
    • 2015-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-04
    • 1970-01-01
    相关资源
    最近更新 更多