首页 > 解决方案 > SQLite3:如何使用 200 多个“FROM”子句进行“LEFT JOIN”?

问题描述

我正在尝试制定一个 SQLite 3 语句(使用 Python 的 sqlite3 库执行),它连接一堆具有相同列和索引的表,以形成一个汇总所有数据的大表(最终将作为CSV)。

脚本的问题部分如下所示。

with sqlite3.connect("database.db") as conn:
    # Create a statment to merge individual tables into one big table indexed by index_col,
    # with columns representing individual sets of values.
    all_column_names = ["<the tables' names, which will be column names in the final table>"]
    all_column_names_as = ", ".join(f'{n}.value AS "{n}"' for n in all_column_names)
    all_joins = "\n".join(f"LEFT JOIN {n} ON {n}.index_col={all_column_names[0]}.index_name" for n in all_column_names[1::])
    select_statement = f"""
           SELECT {all_column_names[0]}.index_col, {all_column_names_as}
           FROM {all_column_names[0]}
           {all_joins};
        """
    # Execute the SELECT statement.
    conn.execute(select_statement)

为了更好地解释,这三个列表推导式创建了一些术语,这些术语组合成一个大SELECT语句,然后执行。该声明如下所示:

SELECT table_0.index_col, table_0.value AS table_0, table_1.value AS table_1, table_2.value AS table_2
FROM table_0
LEFT JOIN table_1 ON table_1.index_col=table_0.index_col
LEFT JOIN table_2 ON table_2.index_col=table_0.index_col;

较小的table_0..2表是这样创建的。

CREATE TABLE IF NOT EXISTS
   table_0 (
      index_col INTEGER PRIMARY KEY,
      value REAL
   );

这会生成一个如下所示的表:

// E.g., table_0; they all look like this.
index_col table_0
01        0.001     
02        0.5      
03        0.1   

// Final table
index_col table_0 table_1 table_2
01        0.001   0.0012  0.01   
02        0.5     0.62    0.67   
03        0.1     0.2     0.15

我遇到的问题与 a 中FROM子句的最大限制有关LEFT JOIN,即 200。

Traceback (most recent call last):
  File "<redacted>", line <redacted>, in execute
    cur.execute(*args, **kwargs)
sqlite3.OperationalError: too many FROM clause terms, max: 200

显然,这不是一种有效的方法,并且重新编译 SQLite 二进制文件以允许超过 200 个FROM子句是不可接受的。

我正在寻找任何可以计算相同决赛桌但不会失败的解决方案。如果这需要LEFT JOINs 制作部分表格,然后最后将它们组合起来,那没关系。如果有更好的方法来编写不会遇到限制的 SQL 语句,或者只是实现相同目的的不同 SQL 语句,那也很好。

背景:之所以使用SQL,是因为我受到RAM的限制;写入磁盘速度较慢,但​​允许我对数据进行操作,因为行的返回类似于 Python 生成器。以前,尝试使用本地 Python 数据类型和内存中的 Pandas DataFrames 生成然后连接数据导致我用完 RAM,所以我不会在 Pandas(或其他库)中寻找解决方案,除非它更容易实现.

标签: pythonsqldatabasesqlitebigdata

解决方案


推荐阅读