【问题标题】:Postgresql 9.2.2. There is an entry for table "xxx", but it cannot be referenced from this part of the queryPostgreSQL 9.2.2。表“xxx”有一个条目,但不能从这部分查询中引用
【发布时间】:2019-01-14 12:20:05
【问题描述】:

当我尝试在 Postgresql 9.2.2 中执行下一个查询时收到错误消息。

SELECT emp_wallet_periods.employer_id, t.ttl as total, COALESCE(t.imported,0), COALESCE(t.spend, 0), COALESCE(t.available, 0), emp_wallet_periods.year, emp_wallet_periods.month
    FROM (
        SELECT employer_id,
            CAST (date_part('month', to_timestamp(date_created)) AS INTEGER) as month,
            CAST (date_part('year', to_timestamp(date_created)) AS INTEGER) as year
        FROM z_employer_wallet
        WHERE state = 1
        GROUP BY 1, 2, 3) as emp_wallet_periods
    INNER JOIN get_employers_availability_by_month(emp_wallet_periods.employer_id, emp_wallet_periods.year, emp_wallet_periods.month) as t ON t.employerId = emp_wallet_periods.employer_id
    ORDER BY emp_wallet_periods.year DESC, t.available DESC, emp_wallet_periods.month DESC

同样的查询在 Postgresql 9.5.6 中完美运行。

我收到的确切错误消息是:

错误:对表的 FROM 子句条目的引用无效 “emp_wallet_periods”第 9 行:内部联接 get_employers_availability_by_month(emp_wallet_p...

^ 提示:表“emp_wallet_periods”有一个条目,但不能 从查询的这一部分引用。

我想念什么?

【问题讨论】:

  • 感谢 Lelio Faieta 的编辑。 :)

标签: php postgresql


【解决方案1】:

不幸的是,这种语法在 Postgres 9.2 中不可用。 FROM 子句子查询和函数调用的 LATERAL 选项在 Postgres 9.3. 中引入

【讨论】:

    【解决方案2】:

    语法是T1 { [INNER] | { LEFT | RIGHT | FULL } [OUTER] } JOIN T2 ON boolean_expression https://www.postgresql.org/docs/9.2/static/queries-table-expressions.html

    如您所见,您不能在 JOIN 中使用函数

    ...get_employers_availability_by_month(emp_wallet_periods.employer_id, emp_wallet_periods.year, emp_wallet_periods.month) as t...
    

    你可以做的是SELECT get_employers_availability_by_month(emp_wallet_periods.employer_id, emp_wallet_periods.year, emp_wallet_periods.month) FROM original_query

    并加入结果。

    【讨论】:

    • 嗨,Alexey Soshin。你能举一些相关的例子吗?老实说,我是 Postgresql 的新手,我不太了解你。对此感到抱歉。
    • 非常感谢您的快速响应 Alexey。我会测试您的建议,并会回来分享结果。
    • 朋友@arturios 已经写了我的意思,请检查他的答案。
    【解决方案3】:
    SELECT emp_wallet_periods.employer_id, t.ttl as total, COALESCE(t.imported,0), COALESCE(t.spend, 0), COALESCE(t.available, 0), emp_wallet_periods.year, emp_wallet_periods.month
        FROM (
            SELECT employer_id,
                CAST (date_part('month', to_timestamp(date_created)) AS INTEGER) as month,
                CAST (date_part('year', to_timestamp(date_created)) AS INTEGER) as year
            FROM z_employer_wallet
            WHERE state = 1
            GROUP BY 1, 2, 3) as emp_wallet_periods
        INNER JOIN (SELECT get_employers_availability_by_month(emp_wallet_periods.employer_id, emp_wallet_periods.year, emp_wallet_periods.month)
                    FROM (SELECT employer_id,
                                CAST (date_part('month', to_timestamp(date_created)) AS INTEGER) as month,
                                CAST (date_part('year', to_timestamp(date_created)) AS INTEGER) as year
                            FROM z_employer_wallet
                            WHERE state = 1
                            GROUP BY 1, 2, 3) as emp_wallet_periods) as t 
        ON t.employerId = emp_wallet_periods.employer_id
        ORDER BY emp_wallet_periods.year DESC, t.available DESC, emp_wallet_periods.month DESC
    

    【讨论】:

    • 不。不在 9.2 中。
    • 非常感谢@arturios 的回复。我会测试你的建议并回来分享结果。
    • 嗨@arturios。我测试了你的建议,但不起作用。我试图重写查询的某些部分,但仍然无法正常工作。我收到的主要问题是 t.employer_id 不存在,因为 INNER JOIN 检索某种数组作为结果。
    • 我认为你需要看看你的函数返回了什么,你的函数应该返回一个表才能工作。
    • 我将把我的函数粘贴为答案。该函数返回表。
    【解决方案4】:

    这是我的完整原始函数 get_employers_availability_by_month();

    CREATE OR REPLACE FUNCTION get_employers_availability_by_month(eid integer, y integer, m integer)
    RETURNS TABLE(employerId integer, ttl real, imported real, spend real, available real, year integer, month integer) AS $$
    BEGIN
        RETURN QUERY
        SELECT emp_wallet.employer_id, SUM(emp_wallet.total) as total, emp_wallet_imported.imported, emp_wallet_spend.spend, CASE WHEN (emp_wallet_spend.spend > 0 AND emp_wallet_imported.imported is null) THEN CAST((0 - emp_wallet_spend.spend) as real)
            WHEN emp_wallet_spend.spend > 0 THEN (emp_wallet_imported.imported-emp_wallet_spend.spend)
            ELSE emp_wallet_imported.imported END AS availability, CAST(date_part('year', to_timestamp(emp_wallet.date_created)) as INTEGER) as year, CAST(date_part('month', to_timestamp(emp_wallet.date_created)) as INTEGER) as month
        FROM z_employer_wallet as emp_wallet
        LEFT JOIN (
            SELECT employer_id, SUM(total) AS imported
                FROM z_employer_wallet as emp_wal
                WHERE emp_wal.total > 0
                    AND emp_wal.flow = 1
                    AND emp_wal.state = 1
                    AND emp_wal.employer_id = eid
                    AND date_part('year', to_timestamp(emp_wal.date_created)) = y
                    AND date_part('month', to_timestamp(emp_wal.date_created)) = m
                GROUP BY employer_id
            ) as emp_wallet_imported ON emp_wallet_imported.employer_id = emp_wallet.employer_id
        LEFT JOIN (
            SELECT employer_id, SUM(total) AS spend
                FROM z_employer_wallet as emp_wal
                WHERE emp_wal.total > 0
                    AND emp_wal.flow = 2
                    AND emp_wal.state = 1
                    AND emp_wal.employer_id = eid
                    AND date_part('month', to_timestamp(emp_wal.date_created)) = m
                    AND date_part('year', to_timestamp(emp_wal.date_created)) = y
                GROUP BY employer_id
        ) as emp_wallet_spend ON emp_wallet_spend.employer_id = emp_wallet.employer_id
        WHERE emp_wallet.employer_id = eid
            AND date_part('month', to_timestamp(emp_wallet.date_created)) = m
            AND date_part('year', to_timestamp(emp_wallet.date_created)) = y
        GROUP BY emp_wallet.employer_id, emp_wallet_imported.imported, emp_wallet_spend.spend, date_part('month', to_timestamp(emp_wallet.date_created)), date_part('year', to_timestamp(emp_wallet.date_created))
        ORDER BY emp_wallet.employer_id DESC;
    RETURN;
    END
    $$
    LANGUAGE plpgsql;
    

    【讨论】:

    • 我没有找到我的问题的解决方案。非常感谢大家的帮助。我将重写查询。祝你有美好的一天。
    猜你喜欢
    • 1970-01-01
    • 2015-07-13
    • 2019-01-06
    • 2016-06-19
    • 2014-08-08
    • 2018-11-17
    • 2019-11-04
    • 1970-01-01
    • 2021-12-25
    相关资源
    最近更新 更多