SQLite 递归 CTE 计算列表(列表)中的项目数

SQLite recursive CTE to calculate number of items in list (of lists)

我有一个 table 列表 ...

和第二个 table ListItem.

ListItem中的“parentId”列指向该项所属的List。当我 运行 下面的 SQLite 查询时...

WITH RECURSIVE x (id, name, parentId, totalNumberOfItems)
AS (
SELECT ID, Name, parentId, (SELECT COUNT(*) FROM listitem WHERE parentId = list.id) as totalNumberOfItems
FROM List 
WHERE parentId is NULL
UNION ALL
SELECT e.id, e.name, e.parentId, (SELECT COUNT(*) FROM listitem WHERE parentId = e.id) as totalNumberOfItems
FROM list e INNER JOIN x on e.parentId = x.ID
)
select * from x

然后我得到以下结果:

但是,我想知道 List1 及其子列表(List2 + List3 + ... 等)中有多少项,因此对于 List1,totalNumberOfItems 是 6。

下面是一个允许创建 Db-Schema 和插入数据的脚本。

BEGIN TRANSACTION;
CREATE TABLE IF NOT EXISTS "List" (
    "id"    INTEGER NOT NULL,
    "name"  TEXT NOT NULL,
    "parentId"  INTEGER,
    PRIMARY KEY("id" AUTOINCREMENT)
);
CREATE TABLE IF NOT EXISTS "ListItem" (
    "id"    INTEGER NOT NULL,
    "name"  TEXT NOT NULL,
    "parentId"  INTEGER NOT NULL,
    PRIMARY KEY("id" AUTOINCREMENT),
    FOREIGN KEY("parentId") REFERENCES "List"("id")
);
INSERT INTO "List" ("id","name","parentId") VALUES (1,'List1',NULL),
 (2,'List2',1),
 (3,'List3',2);
INSERT INTO "ListItem" ("id","name","parentId") VALUES (1,'Item1',1),
 (2,'Item2',1),
 (3,'Item3',2),
 (4,'Item4',1),
 (5,'Item5',2),
 (6,'Item6',3);
COMMIT;

使用递归 CTE,returns 您想要的列表的 ID 及其低于最低级别的所有子项。

然后使用该查询的结果在 table ListItem 中聚合:

WITH cte AS (
  SELECT id FROM List WHERE name = 'List1' 
  UNION ALL
  SELECT l.id
  FROM List l INNER JOIN cte c
  ON l.parentId = c.id
)
SELECT COUNT(*) count FROM ListItem WHERE parentId IN cte;

参见demo