<column> 在两个表之间的列比较中不明确
<column> is ambiguous in column comparison between two tables
我想让这个 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 Error [42702]: ERROR: column reference "match_id" is ambiguous
Detail: It could refer to either a PL/pgSQL variable or a table
column. Where: PL/pgSQL function
difference_of_match_ids_in_match_history_and_match_results() line 3 at
RETURN QUERY
我看到其他问题也有同样的错误,他们建议命名子查询以指定您所指的列的哪个实例,但是,这些示例使用联接并且我的查询在功能。
如果我确实需要为列命名,我将如何仅使用一个子查询来命名?
如果这不是问题所在,那么我假设我定义函数的方式有问题。
您的查询没问题。歧义在于 returns table(match_id BIGINT)
中的 match_id
重命名它或在查询
中使用 table 名称作为列前缀
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';
或
CREATE OR REPLACE FUNCTION difference_of_match_ids_in_match_history_and_match_results()
returns table(match_id BIGINT)
as
$$
BEGIN
return QUERY
SELECT sports.match_history.match_id
FROM sports.match_history
WHERE sports.match_history.match_id NOT IN (SELECT sports.match_results.match_id
FROM sports.match_results);
END $$
LANGUAGE 'plpgsql';
没有测试代码。
结果集的结构必须与函数结果类型匹配。如果你只想得到 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';
正如其他人回答的那样,结果定义和 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;
请注意,语言名称是一个标识符,根本不应该被引用。
列名和 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
);
更多:
- Select rows which are not present in other table
我想让这个 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 Error [42702]: ERROR: column reference "match_id" is ambiguous
Detail: It could refer to either a PL/pgSQL variable or a table column. Where: PL/pgSQL function difference_of_match_ids_in_match_history_and_match_results() line 3 at RETURN QUERY
我看到其他问题也有同样的错误,他们建议命名子查询以指定您所指的列的哪个实例,但是,这些示例使用联接并且我的查询在功能。
如果我确实需要为列命名,我将如何仅使用一个子查询来命名?
如果这不是问题所在,那么我假设我定义函数的方式有问题。
您的查询没问题。歧义在于 returns table(match_id BIGINT)
中的 match_id
重命名它或在查询
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';
或
CREATE OR REPLACE FUNCTION difference_of_match_ids_in_match_history_and_match_results()
returns table(match_id BIGINT)
as
$$
BEGIN
return QUERY
SELECT sports.match_history.match_id
FROM sports.match_history
WHERE sports.match_history.match_id NOT IN (SELECT sports.match_results.match_id
FROM sports.match_results);
END $$
LANGUAGE 'plpgsql';
没有测试代码。
结果集的结构必须与函数结果类型匹配。如果你只想得到 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';
正如其他人回答的那样,结果定义和 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;
请注意,语言名称是一个标识符,根本不应该被引用。
列名和 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
);
更多:
- Select rows which are not present in other table