【问题标题】:How to return different format of records from a single PL/pgSQL function?如何从单个 PL/pgSQL 函数返回不同格式的记录?
【发布时间】:2022-01-30 10:41:19
【问题描述】:

我是一名前端开发人员,但我开始编写后端的东西。我花了相当多的时间试图弄清楚如何解决这个问题。我真的需要一些帮助。

以下是两个表的简化定义和关系:

Relationship between tables

CREATE TABLE IF NOT EXISTS items (
    item_id       uuid          NOT NULL DEFAULT gen_random_uuid() ,
    parent_id     uuid                   DEFAULT NULL              ,   
    parent_table  parent_tables NOT NULL
);
CREATE TABLE IF NOT EXISTS collections (
    collection_id uuid          NOT NULL DEFAULT gen_random_uuid() ,
    parent_id     uuid                   DEFAULT NULL
);

我们的产品是一个在线文档协作工具,页面可以有嵌套页面。

我有一段 PostgreSQL 代码用于获取给定 item_ids 的所有祖先记录。

WITH RECURSIVE ancestors AS (
    SELECT *
    FROM items
    WHERE item_id in ( ${itemIds} )

    UNION

    SELECT i.*
    FROM items i
    INNER JOIN ancestors a ON a.parent_id = i.item_id
)
SELECT * FROM ancestors

它适用于嵌套常规页面,但是如果我要支持嵌套集合页面,这意味着某些项目的 parent_id 可能引用“集合”表的集合 ID,此代码将不再工作。根据我有限的经验,我认为纯 SQL 代码无法解决。我认为编写一个 PL/pgSQL 函数可能是一个解决方案,但我需要将所有祖先记录获取给给定的itemIds,这意味着返回项目和集合记录的混合。

那么如何从单个 PL/pgSQL 函数返回不同格式的记录呢?我做了一些研究,但没有找到任何例子。

【问题讨论】:

标签: postgresql plpgsql common-table-expression recursive-query


【解决方案1】:

您可以通过返回超集作为行来使其工作:由项目集合组成。对于每个结果行,两者之一将是 NULL

WITH RECURSIVE ancestors AS (
   SELECT 0 AS lvl, i.parent_id, i.parent_table, i AS _item, NULL::collections AS _coll
   FROM   items i
   WHERE  item_id IN ( ${itemIds} )

   UNION ALL -- !
   SELECT lvl + 1, COALESCE(i.parent_id, c.parent_id), COALESCE(i.parent_table, 'i'), i, c
   FROM   ancestors        a 
   LEFT   JOIN items       i ON a.parent_table = 'i' AND i.item_id = a.parent_id
   LEFT   JOIN collections c ON a.parent_table = 'c' AND c.collection_id = a.parent_id
   WHERE  a.parent_id IS NOT NULL
   )
SELECT lvl, _item, _coll
FROM   ancestors
--     ORDER BY ?

db小提琴here

UNION ALL,不是UNION

假设一个集合的父级总是一个项目,而一个项目可以去任何方向。

我们需要LEFT JOIN 在两个潜在的父表上保持竞争。

我添加了一个可选的lvl 来跟踪层次结构的级别。

关于分解行类型:

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-08-05
    • 2013-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多