在 SQLite3 中创建一个视图,通过树状数据库结构列出所有唯一路径

Create a view in SQLite3 that lists all unique paths through tree-like database structure

我正在使用 SQLite3(和 python,但这对问题并不重要,我认为)在具有多个嵌套级别的分层装配体中构建零件数据库,其中每个零件程序集中可以有多个变体。数据库可以包括来自多个组件的条目,这些组件可能具有不同数量的成员零件。我有一个 table,每个唯一部件都有一个条目,其中有一列用于部件 ID,一列用于装配 ID,一列用于装配层次结构中父部件的 ID(如果有)。此外,我还有第二个 table,其中列出了所有零件的独特变体,其中包含零件属性列和装配零件的 ID 号列,该条目是其变体。

我希望能够为 程序集 的每个可能的独特变体构建一个列表。是否可以将此作为 SQLite 数据库中的视图来执行,如果可以,我将如何构建该查询?或者有什么方法可以让我的数据库结构不同,从而使这项任务更容易吗?

编辑:
样本结构:

Table: "PARTS"
PART_ID  PART_NAME   PARENT  ASSEMBLY
1        'Foo'       NULL    1
2        'Bar'       1       1
3        'Thing'     1       1
4        'Doodad'    1       1
5        'Bauble'    3       1
6        'Oof'       NULL    2
7        'Rab'       6       2
8        'Trinket'   6       2

Table: "VARIATIONS"
VAR_ID   PART_ID    PROPERTY_1   PROPERTY_2   PROPERTY_3
1        1          3.14159      0.63         0
2        1          3.24359      0.68         1
3        1          3            0.5          0.9999999
4        2          0.1          0.1          0.1
5        3          0.11         0.01         0.0005
6        3          0.11         0.01         0.0006
7        4          0.05         0.05         0.05
8        5          0.001        0.08         0.001
9        5          0.001        0.085        0.0011
10       6          5.5          1.0          3.2
11       7          1.1          0.99         1.2
12       8          0.05         0.05         0.05

我想列出装配体中所有可能的变体零件组合,上面 table 中装配体 1 中的零件看起来像这样。下面的列是 VAR_ID 来自相应零件号的变体 table。

ROWNUM   PART1_VAR  PART2_VAR  PART3_VAR  PART4_VAR PART5_VAR
1        1          4          5          7         8
2        2          4          5          7         8
3        3          4          5          7         8
4        1          4          6          7         8
5        2          4          6          7         8
6        3          4          6          7         8
7        1          4          5          7         9
8        2          4          5          7         9
9        3          4          5          7         9
10       1          4          6          7         9
11       2          4          6          7         9
12       3          4          6          7         9

在长期中断后回到这个项目,并通过在 python 中即时手动构建查询使其工作。正如@DinoCoderSaurus 指出的那样,实际上不可能创建一个单独的 table 列出示例中所有程序集的变体,但我能够为每个程序集创建一个单独的 table 程序集变体组装.

应该与问题中的示例一起使用的 python 代码如下所示。它不优雅,但它有效。

assembly = 1
          
#List fragments from current assembly in hierarchical order
query = f'''
    WITH RECURSIVE
        hierarchy(PART,LEVEL) AS (
        VALUES('',0)
        UNION ALL
        SELECT PARTS.PART_ID, hierarchy.LEVEL+1
            FROM PARTS JOIN hierarchy ON PARTS.PARENT=hierarchy.FRAGMENT
            WHERE PARTS.ASSEMBLY={assembly}
            ORDER BY 2
        )
        SELECT PART FROM hierarchy;
    '''
parts = [qq[0] for qq in cursor.execute(query).fetchall()[1:]]
# Create SQL-friendly column names from the list of part IDs
colnames = [f'PART_{qq}' for qq in parts]
# Generate a dictionary of parent parts for each part
parents = {f'PART_{c}':f'PART_{p}' for c,p in self.query('SELECT PART_ID,PARENT FROM PARTS')}

# Generate a long query of as many successive join statements between temporary 
# tables as it takes to traverse the assembly hierarchy tree, deleting each 
# previous temporary table as you go.
joins = '\n'.join([f"""
    CREATE TEMPORARY TABLE new_table_{ii:d}({' TEXT, '.join(colnames[:ii+1])} TEXT); 
    INSERT INTO new_table_{ii:d}  
        SELECT new_table_{ii-1:d}.*, VAR_ID 
            FROM new_table_{ii-1:d} 
                INNER JOIN VARIATIONS 
                        ON PARENT_VAR=new_table_{ii-1:d}.{parents[colnames[ii]]} 
                            AND PART_ID = '{fragments[ii]}';
    DROP TABLE new_table_{ii-1:d};""" for ii in range(1,len(colnames))])
scrpt = f'''
    CREATE TEMPORARY TABLE new_table_0({colnames[0]} TEXT);
    INSERT INTO new_table_0
        SELECT VAR_ID FROM VARIATIONS
                WHERE PARENT_VAR = ''
                AND PART_ID = '{fragments[0]}';
    {joins}
    ALTER TABLE new_table_{len(colnames)-1:d} RENAME TO ASSEMBLY_{assembly}_VARIATIONS;
'''
self._cursor.executescript(scrpt)