为什么此 SQLite 查询中的 GROUP_CONCAT 在最新版本中不起作用?

Why is GROUP_CONCAT in this SQLite query not working in recent versions?

几年前我写了一个 Python 瓶子应用程序,它使用了以下查询:

SELECT * FROM (
    SELECT a.*,
    GROUP_CONCAT(st.ID) AS Sentences
    FROM (
        SELECT sc.ID, sc.Title_PT, sc.Title_DE, sc.Parent_ID, GROUP_CONCAT(sc2.ID) AS Children
        FROM Section AS sc
        LEFT JOIN Section AS sc2 ON sc2.Parent_ID = sc.ID
        GROUP BY sc2.Parent_ID
    ) AS a
    LEFT JOIN Sentence AS st ON st.Section_ID = a.ID
    GROUP BY a.ID
    UNION
    SELECT sc.ID, sc.Title_PT, sc.Title_DE, sc.Parent_ID, NULL AS Children, GROUP_CONCAT(st.ID) AS Sentences
    FROM Section AS sc
    LEFT JOIN Sentence AS st ON st.Section_ID = sc.ID
    GROUP BY sc.ID
)
GROUP BY ID
ORDER BY Parent_ID;

它曾经正确地 return 类似于:

ID  |Title_PT   |Title_DE   |Parent_ID  |Children   |Sentences
1   |Idioma geral 1 - Expressões comuns em contextos específicos    |Gebräuchliche Ausdrücke in spezifischen Kontexten      |2,7,8,12,20,25,26,30,38,39,42,43,44,45,50,54,58,59,60,71,72,73,76,77,78,89,92,93,123,127,142   |2530,2571

其中每一行提到 本书的一个章节 (Section.ID),其 小节的 ID(儿童列) 和属于该部分(句子列) 的所有单个 句子的 ID。我已经在 SQLite Expert Professional 的旧版本(3.5,从 2013 年开始)上对此进行了测试,它 运行 没问题。

但是,当我 运行 在较新版本的 sqlite3.exe(3.35.5,从 2021 年开始)中进行相同的查询时,字段“儿童”return s NULL for all rows(所以,我不知道,GROUP_CONCAT 不再工作了):

ID  |Title_PT   |Title_DE   |Parent_ID  |Children   |Sentences
1   |Idioma geral 1 - Expressões comuns em contextos específicos    |Gebräuchliche Ausdrücke in spezifischen Kontexten      |NULL   |2530,2571

我也尝试用 Python 3.10 和 sqlite3 库重现它,但我遇到了同样的问题。有谁知道最近的 SQLite 中可能发生了什么变化,破坏了我的代码?

数据库中的模式(一本多语言的句子书,由 sections/topics 组织,以及其他语言的对应物):

CREATE TABLE [Sentence] (
        ID INTEGER PRIMARY KEY,
        Section_ID INTEGER,
        Sentence_PT CHAR(1024) NOT NULL,
        Sentence_DE CHAR(1024),
        Sentence_EN CHAR(1024),
        Sentence_ES CHAR(1024)
);
CREATE TABLE [Section] (
        ID INTEGER PRIMARY KEY,
        Parent_ID INTEGER REFERENCES Section(ID),
        Title_PT CHAR(1024),
        Title_DE CHAR(1024),
        Title_EN CHAR(1024),
        Title_ES CHAR(1024)
);

编辑:这是一个fiddle:https://dbfiddle.uk/?rdbms=sqlite_3.27&fiddle=c31242bb38d85afcd1acfc8f57d1dd99

实际上,您使用旧版 SQLite 获得的正确结果恰好是正确的。
在您的代码中,您仅按 1 列和 select 许多 GROUP BY 子句中不存在的列分组。
这在大多数数据库中是不允许的,但 SQLite 允许它,这会导致意外结果,因为 SQLite 选择一个(几乎)任意行来 select 所有未聚合列的值。

由于这是您的代码,您可以使用函数 MAX() 对列 Children 进行聚合以获得 non-null 值(如果存在):

SELECT ID, Title_PT, Title_DE, Parent_ID ,
       MAX(Children) AS Children,
       Sentences
FROM (
    SELECT a.*,
           GROUP_CONCAT(st.ID) AS Sentences
    FROM (
        SELECT sc.ID, sc.Title_PT, sc.Title_DE, sc.Parent_ID, GROUP_CONCAT(sc2.ID) AS Children
        FROM Section AS sc
        LEFT JOIN Section AS sc2 ON sc2.Parent_ID = sc.ID
        GROUP BY sc2.Parent_ID
    ) AS a
    LEFT JOIN Sentence AS st ON st.Section_ID = a.ID
    GROUP BY a.ID
    UNION
    SELECT sc.ID, sc.Title_PT, sc.Title_DE, sc.Parent_ID, NULL AS Children, GROUP_CONCAT(st.ID) AS Sentences
    FROM Section AS sc
    LEFT JOIN Sentence AS st ON st.Section_ID = sc.ID
    GROUP BY sc.ID
)
GROUP BY ID
ORDER BY Parent_ID;

参见demo