当我尝试在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”有一个条目,但不能 从查询的这一部分引用。
我想念什么?
答案 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;