我希望这个postgres功能起作用:
CREATE OR REPLACE FUNCTION difference_of_match_ids_in_match_history_and_match_results()
returns table(match_id BIGINT)
as
$$
BEGIN
return QUERY
SELECT *
FROM sports.match_history
WHERE match_id NOT IN (SELECT match_id
FROM sports.match_results);
END $$
LANGUAGE 'plpgsql';
这个独立的查询工作正常:
SELECT *
FROM sports.match_history
WHERE match_id NOT IN (SELECT match_id FROM sports.match_results);
但是当我把它放到这个函数中并尝试像这样运行它时:
select *
from difference_of_match_ids_in_match_history_and_match_results();
我明白了:
SQL错误[42702]:错误:列引用“match_id”不明确
细节:它可以指PL / pgSQL变量或表 柱。其中:PL / pgSQL函数 difference_of_match_ids_in_match_history_and_match_results()第3行 返回查询
我已经看到了同样错误的其他问题,他们建议命名子查询以指定您所引用的列的哪个实例,但是,这些示例使用连接并且我的查询在函数之外工作正常。
如果我确实需要为列命名,那么如何只使用一个子查询?
如果那不是问题,那么我假设我定义一个函数的方式有问题。
答案 0 :(得分:1)
你查询没问题。歧义位于<tr>
match_id
重命名,或者在查询中使用表名称添加前缀
returns table(match_id BIGINT)
或
CREATE OR REPLACE FUNCTION difference_of_match_ids_in_match_history_and_match_results()
returns table(new_name BIGINT)
as
$$
BEGIN
return QUERY
SELECT *
FROM sports.match_history
WHERE match_id NOT IN (SELECT match_id
FROM sports.match_results);
END $$
LANGUAGE 'plpgsql';
没有测试代码。
答案 1 :(得分:1)
结果集的结构必须与函数结果类型匹配。如果您只想获得match_ids
:
CREATE OR REPLACE FUNCTION difference_of_match_ids_in_match_history_and_match_results()
RETURNS TABLE(m_id BIGINT) -- !!
AS
$$
BEGIN
RETURN QUERY
SELECT match_id -- !!
FROM sports.match_history
WHERE match_id NOT IN (SELECT match_id
FROM sports.match_results);
END $$
LANGUAGE 'plpgsql';
如果你想得到整行:
DROP FUNCTION difference_of_match_ids_in_match_history_and_match_results();
CREATE OR REPLACE FUNCTION difference_of_match_ids_in_match_history_and_match_results()
RETURNS SETOF sports.match_history -- !!
AS
$$
BEGIN
RETURN QUERY
SELECT * -- !!
FROM sports.match_history
WHERE match_id NOT IN (SELECT match_id
FROM sports.match_results);
END $$
LANGUAGE 'plpgsql';
答案 2 :(得分:1)
正如其他人所回答的那样,结果定义和PL / pgSQL变量之间存在歧义。集合返回函数中的列名实际上也是函数内的变量。
但是你首先不需要PL / pgSQL。如果使用普通的SQL函数,它将更有效,问题也会消失:
CREATE OR REPLACE FUNCTION difference_of_match_ids_in_match_history_and_match_results()
returns table(match_id BIGINT)
as
$$
SELECT match_id --<< do not return * - only return one column
FROM sports.match_history
WHERE match_id NOT IN (SELECT match_id
FROM sports.match_results);
$$
LANGUAGE sql;
请注意,语言名称是标识符,根本不应引用。
答案 3 :(得分:0)
已解决了列名和plpgsql OUT
参数之间的命名冲突。更多细节在这里:
我还会使用不同的查询样式。 NOT IN (SELECT ...)
通常最慢,并带有NULL值的陷阱。请改用NOT EXISTS
:
SELECT match_id
FROM sports.match_history h
WHERE NOT EXISTS (
SELECT match_id
FROM sports.match_results
WHERE match_id = h.match_id
);
更多: