在 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)
我正在使用 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)