【问题标题】:Reusing results from a SQL query in a following query in Sqlite在 Sqlite 的以下查询中重用 SQL 查询的结果
【发布时间】:2014-02-16 10:56:13
【问题描述】:

我正在使用递归 with 语句在表示树状结构条目的表中从给定父级中选择所有子级。这是在 Sqlite 中(现在支持递归)。
这使我可以非常快速地选择这棵树中的数千条记录,而不会因从调用应用程序准备数千条选择语句而遭受巨大的性能损失。

WITH RECURSIVE q(Id) AS
(
    SELECT Id FROM Entity
    WHERE Parent=(?)
    UNION ALL
    SELECT m.Id FROM Entity AS m
    JOIN Entity ON m.Id=q.Parent
)
SELECT Id FROM q;

现在,假设我在任意数量的其他表中都有与这些实体相关的数据,我想随后加载这些数据。由于它们的数量是任意的(以模块化方式),因此不可能将数据获取直接包含在其中。他们必须遵守它。

但是,如果我为每个相关的表执行一个 SELECT 语句,那么直接在 Sqlite 内部从树中选择所有数据所带来的所有性能增益几乎是无用的,因为我仍然会在数以千计的后续请求上停滞不前,这些请求将分别准备和发出一个 select 语句。

所以两个问题:

  1. 更好的解决方案是为每个相关表制定一个类似的递归语句,它将再次递归地从该树中收集实体,这次通过加入来选择它们的相关数据。 这听起来确实更有效率,但是要制定这样的声明真的很棘手,我在这里有点迷失了。

  2. 1234563以下语句中的相关表无需再次递归迭代?

这是第一个选项的尝试,假设我想从相关表组件中选择一个字段数据:第二个 UNION ALL 合法吗?

WITH RECURSIVE q(Data) AS
(
    SELECT Id FROM Entity
    WHERE Parent=(?)
    UNION ALL
    SELECT m.Id FROM Entity AS m
    JOIN Entity ON m.Id=q.Parent
    UNION ALL
    SELECT Data FROM Component AS c
    JOIN Component ON c.Id=q.Id
)
SELECT Data FROM q;

【问题讨论】:

    标签: sql sqlite recursive-query with-statement


    【解决方案1】:

    documentation 说:

    2. 在 AS 关键字左侧命名的表必须在复合 select 的最右侧 SELECT 语句的 FROM 子句中恰好出现一次,并且不能出现在其他任何地方。

    所以你的第二个查询是不合法的。

    但是,CTE 的行为类似于普通表/视图,因此您可以将其加入相关表:

    WITH RECURSIVE q(Id) AS
    ( ... )
    SELECT q.Id, c.Data
    FROM q JOIN Component AS c ON q.Id = c.Id
    

    如果您想为多个查询重用 q 中的计算值,您无法使用 CTE 执行任何操作,但您可以将它们存储在临时表中:

    CREATE TEMPORARY TABLE q_123 AS
    WITH RECURSIVE q(Id) AS
    ( ... )
    SELECT Id FROM q;
    
    SELECT * FROM q_123 JOIN Component ...;
    SELECT * FROM q_123 JOIN Whatever ...;
    
    DROP TABLE q_123;
    

    【讨论】:

    • 不错!您认为对于这样的用例(10 000 条记录),创建临时表会比第一个选项更有趣吗?我会尝试这些解决方案并回复您
    猜你喜欢
    • 2021-10-27
    • 2013-11-01
    • 1970-01-01
    • 2020-05-15
    • 2023-03-18
    • 2020-12-25
    • 1970-01-01
    • 1970-01-01
    • 2023-03-24
    相关资源
    最近更新 更多