为什么此 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。
几年前我写了一个 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。