PostgreSQL 9.2.2。表“ xxx”有一个条目,但不能在查询的这一部分中引用它

时间:2018-08-07 11:59:47

标签: php postgresql

当我尝试在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行:INNER JOIN   get_employers_availability_by_month(emp_wallet_p ...

     

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

我想念什么?

4 个答案:

答案 0 :(得分:2)

不幸的是,该语法在Postgres 9.2中不可用。 Postgres 9.3.

中引入了FROM子句和函数调用的LATERAL选项

答案 1 :(得分:1)

语法为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

并加入结果。

答案 2 :(得分:1)

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

答案 3 :(得分:0)

这是我完整的原始函数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;

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;