【问题标题】:Oracle SQL invalid identifier error in nested WITH subquery嵌套 WITH 子查询中的 Oracle SQL 无效标识符错误
【发布时间】:2016-07-29 18:27:37
【问题描述】:

您将在下面找到三个示例表和数据以及一个查询。此示例可能看起来有些做作,但它是更大(近 1500 行)SQL 查询的一部分。原始查询效果很好,但我在添加一些新功能时遇到了问题。

CREATE TABLE rule_table (
    id_rule_table NUMBER (10),
    name VARCHAR2 (24),
    goal NUMBER (10),
    amount NUMBER (10)
);

INSERT INTO rule_table (id_rule_table, name, goal, amount) VALUES(1, 'lorem', 2, 3);
INSERT INTO rule_table (id_rule_table, name, goal, amount) VALUES(2, 'ipsum', 3, 3);
INSERT INTO rule_table (id_rule_table, name, goal, amount) VALUES(3, 'dolor', 4, 3);

CREATE TABLE content_table (
    id_content_table NUMBER (10),
    name VARCHAR2 (24),
    show_flag NUMBER (10)
);

INSERT INTO content_table (id_content_table, name, show_flag) VALUES(1, 'lorem', 0);
INSERT INTO content_table (id_content_table, name, show_flag) VALUES(2, 'ipsum', 1);
INSERT INTO content_table (id_content_table, name, show_flag) VALUES(3, 'dolor', 1);

CREATE TABLE module_table (
    id_module_table NUMBER (10),
    id_content_table NUMBER (10),
    name VARCHAR2 (24),
    amount NUMBER (10)
);

INSERT INTO module_table (id_module_table, id_content_table, name, amount) VALUES(1, 2, 'lorem', 10);
INSERT INTO module_table (id_module_table, id_content_table, name, amount) VALUES(2, 2, 'ipsum', 11);
INSERT INTO module_table (id_module_table, id_content_table, name, amount) VALUES(3, 2, 'dolor', 12);

SELECT RULE.id_rule_table
FROM rule_table RULE
WHERE (
    CASE
    WHEN RULE.goal <= (

            WITH contentTbl (id_content_table)
            AS (
                SELECT id_content_table
                FROM content_table
                WHERE show_flag = 1
            ),

            modulesTbl (id_content_table, id_module_table)
            AS (
                SELECT C.id_content_table, M.id_module_table
                FROM contentTbl C
                JOIN module_table M ON M.id_content_table = C.id_content_table
                WHERE 4 < M.amount - RULE.amount
            )

            SELECT SUM(M.id_module_table)
            FROM contentTbl C
            JOIN modulesTbl M ON C.id_content_table = M.id_content_table
    )
    THEN 1
    ELSE 0
    END
) = 1;

DROP TABLE rule_table;
DROP TABLE content_table;
DROP TABLE module_table;

如果您尝试此操作,您将收到错误 ORA-00904: "RULE"."AMOUNT": invalid identifier。问题在于“WHERE 4

如果您将该行中的 RULE.amount 替换为某个数字(例如,WHERE 4

如上所述,这是一个来自更大查询的 sn-p 测试用例,因此查询的结构不能(或希望不需要)改变太多。也就是说,理想情况下,我正在寻找一种解决方案,该解决方案允许我在子查询中使用 RULE.amount,而无需更改“WHEN RULE.goal

我正在尝试在 Oracle 11g 上运行它。

最后一件事,我尝试在 google 和 stackoverflow 中搜索解决方案,但我无法找到正确的术语来描述我的问题。最接近的似乎是嵌套的相关子查询,但这似乎并不完全正确。

【问题讨论】:

    标签: sql oracle subquery


    【解决方案1】:

    考虑到这只是更大查询的一部分,以下是完成这项工作所需的外科手术更改:

    1. WHERE 4 &lt; M.amount - RULE.amount 条件从 CTE 移出并进入主查询,以便 RULE 在范围内。

    2. 修改 modulesTbl CTE 以返回额外的列 amount,以便 M.amount 现在可用于主查询。

    通过这 2 项更改,查询将如下所示:

    SELECT RULE.id_rule_table
    FROM rule_table RULE
    WHERE (
        CASE
        WHEN RULE.goal <= (
    
                WITH contentTbl (id_content_table)
                AS (
                    SELECT id_content_table
                    FROM content_table
                    WHERE show_flag = 1
                ),
    
                modulesTbl (id_content_table, id_module_table, amount) -- add amount
                AS (
                    SELECT C.id_content_table, M.id_module_table, M.amount -- add amount
                    FROM contentTbl C
                    JOIN module_table M ON M.id_content_table = C.id_content_table
                )
    
                SELECT SUM(M.id_module_table)
                FROM contentTbl C
                JOIN modulesTbl M ON C.id_content_table = M.id_content_table
                                  AND 4 < M.amount - RULE.amount -- moved from CTE to here
        )
        THEN 1
        ELSE 0
        END
    ) = 1;
    

    【讨论】:

    • ...为了 OP 的利益,所写的查询不起作用的原因是 RULE 对第一级子查询可见(SELECT SUM(...) FROM... ) 但它对二级子查询不可见 (SELECT C.id_content_table .....) Oracle 不会关联嵌套超过一级深度的子​​查询。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 1970-01-01
    • 2022-09-30
    • 2015-09-07
    • 1970-01-01
    相关资源
    最近更新 更多