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

问题描述 投票:0回答:1

每个 List 可以有多个 ListItems (

1 --> n
)。并且一个列表可以有一个父列表。

      List 1
       |
       |-- List Item 1
       |
       |-- List 2  
       |     |              
       |     |-- Liste Item 3
       |
       |-- List 3

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

表格列表看起来像这样

id 名字 家长ID
1 列表1
2 清单2 1
3 列表3 2

表格ListItem看起来像这样

id 名字 家长ID
1 第 1 项 1
2 第 2 项 1
3 第 3 项 2
4 第 4 项 1
5 第 5 项 2
6 第 6 项 3

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

然后我得到以下结果:

下面是一个允许创建 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;
sql sqlite count common-table-expression recursive-query
1个回答
1
投票

使用递归 CTE 返回所需列表及其最低级别以下的所有子列表的 id。

然后使用该查询的结果聚合在表 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;

查看演示

© www.soinside.com 2019 - 2024. All rights reserved.