【问题标题】:ORDER siblings BY and rownum while migrating from Oracle to PostgreSQL从 Oracle 迁移到 PostgreSQL 时 ORDER 兄弟姐妹 BY 和 rownum
【发布时间】:2020-10-19 22:45:12
【问题描述】:

我正在将一个项目从 Oracle 迁移到 PG,但一个 sql 查询出现问题。

这是我的桌子:

CREATE TABLE descriptor_value (
    descriptor_value_id bigint NOT NULL,
    descriptor_group_id bigint NOT NULL,
    full_value varchar(4000) NOT NULL,
    short_value varchar(250),
    value_code varchar(30),
    sort_order bigint NOT NULL,
    parent_value_id bigint,
    deleted smallint NOT NULL DEFAULT 0,
    portal smallint NOT NULL DEFAULT 0
) ;

这是我要迁移的原始 oracle 查询:

select rownum as ROW_NUM, DESCRIPTOR_VALUE_ID 
         from DESCRIPTOR_VALUE
         connect by prior DESCRIPTOR_VALUE_ID = PARENT_VALUE_ID
               start with PARENT_VALUE_ID is null
                      and DESCRIPTOR_GROUP_ID = (select DESCRIPTOR_GROUP_ID
                                                   from DESCRIPTOR_VALUE
                                                  where DESCRIPTOR_VALUE_ID = 867)
               order siblings by SORT_ORDER;

这是我的 postgresql 查询:

WITH RECURSIVE descriptor_values AS (
            SELECT
                    ARRAY[descriptor_value_id] AS hierarchy,
                    descriptor_value_id,
                    parent_value_id,
                    sort_order
            FROM
                    descriptor_value
            WHERE
                    parent_value_id IS NULL AND descriptor_group_id = (
                        SELECT descriptor_group_id
                        FROM descriptor_value
                        WHERE descriptor_value_id = 867)
            UNION ALL
            SELECT
                    descriptor_values.hierarchy || dv.descriptor_value_id,
                    dv.descriptor_value_id,
                    dv.parent_value_id,
                    dv.sort_order
            FROM
                    descriptor_value dv
            JOIN descriptor_values ON dv.parent_value_id = descriptor_values.descriptor_value_id

    ) SELECT
            descriptor_value_id
    FROM
            descriptor_values order by hierarchy;

order siblings by 的解决方案我从这里得到 https://stackoverflow.com/a/17737560/5182503 。但是,postgresql 结果集中的行顺序与 oracle 结果集中的顺序不同。我完全停止了这里的rownum怎么样。谁能帮我建立正确的 pg 查询?

【问题讨论】:

    标签: sql oracle postgresql


    【解决方案1】:

    您链接的解决方案假定descriptor_value_id 存在自然排序。

    如果sort_order 在表中是唯一的,那么下面的查询应该可以工作。

    如果不是,那么我们将不得不在您放入 hierarchy 数组中的值中做一些猴子业务。

    WITH RECURSIVE descriptor_values AS (
                SELECT
                        ARRAY[sort_order] AS hierarchy,
                        descriptor_value_id,
                        parent_value_id,
                        sort_order
                FROM
                        descriptor_value
                WHERE
                        parent_value_id IS NULL AND descriptor_group_id = (
                            SELECT descriptor_group_id
                            FROM descriptor_value
                            WHERE descriptor_value_id = 867)
                UNION ALL
                SELECT
                        descriptor_values.hierarchy || dv.sort_order,
                        dv.descriptor_value_id,
                        dv.parent_value_id,
                        dv.sort_order
                FROM
                        descriptor_value dv
                JOIN descriptor_values ON dv.parent_value_id = descriptor_values.descriptor_value_id
    
        ) SELECT
                descriptor_value_id
        FROM
                descriptor_values
        order by hierarchy;
    

    根据评论更新

    由于sort_order 在整个表中不是唯一的,因此需要将其合并到hierarchy 数组中。我还在最终查询中添加了row_number()

    WITH RECURSIVE descriptor_values AS (
                SELECT
                        ARRAY[sort_order, descriptor_value_id] AS hierarchy,
                        descriptor_value_id,
                        parent_value_id,
                        sort_order
                FROM
                        descriptor_value
                WHERE
                        parent_value_id IS NULL AND descriptor_group_id = (
                            SELECT descriptor_group_id
                            FROM descriptor_value
                            WHERE descriptor_value_id = 867)
                UNION ALL
                SELECT
                        descriptor_values.hierarchy 
                           || array[dv.sort_order, dv.descriptor_value_id]
                        dv.descriptor_value_id,
                        dv.parent_value_id,
                        dv.sort_order
                FROM
                        descriptor_value dv
                JOIN descriptor_values ON dv.parent_value_id = descriptor_values.descriptor_value_id
    
        ) SELECT
                row_number() over (order by hierarchy), 
                hierarchy,
                descriptor_value_id
        FROM
                descriptor_values 
       order by hierarchy;
    

    【讨论】:

    • @Shtirlits 我更新了我的答案。请尝试新的查询,让我知道它是否有效。
    • 非常感谢。我编辑了这一行descriptor_values.hierarchy || array[dv.sort_order, dv.descriptor_value_id],。但是,oracle 中的结果与 pg 中的结果不同。您的解决方案是否假设 sort_order 在一个父级中?例如,如果我们的父 A 有两个孩子 B 和 C,那么 childB 的 sort_order=0,childC 的 sort_order=1。
    • @Shtirlits 它应该考虑排序顺序。尝试将 hierarchy 列添加到您的输出中以查看查询的作用。表中的层次结构是否有多个根元素?如果是这样,我将sort_order 添加到初始数组中。
    • 非常感谢。你最后的解决方案给出了与 oracle 相同的结果。
    猜你喜欢
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 2014-07-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-21
    • 2012-07-23
    相关资源
    最近更新 更多