I keep getting this ERROR: column reference «person» is ambiguous.
It is required of me to return a TABLE (person integer). It works fine when I use SETOF integer but in this instance it doesn’t work. My other function recurse() returns a set of integers perfectly well.
CREATE OR REPLACE FUNCTION try(_group text) RETURNS TABLE (person integer) AS $$
DECLARE
_init_id integer;
_record integer;
BEGIN
SELECT id INTO _init_id FROM egroups WHERE name = _group;
FOR _record in SELECT person FROM egroupdata WHERE egroup IN (SELECT recurse(_init_id))
LOOP
RETURN NEXT;
END LOOP;
END;
$$ language plpgsql stable;
![]()
asked May 25, 2012 at 8:01
1
Ambiguous column references are due to there being more than one column available of the same name. In this case I guess it’s a quirk of returning a table. Try changing the query to:
SELECT egroupdata.person FROM egroupdata WHERE egroup IN (SELECT recurse(_init_id))
This will disambiguate the column reference.
answered May 25, 2012 at 8:39
Philip CoulingPhilip Couling
13k4 gold badges51 silver badges80 bronze badges
0
I keep getting this ERROR: column reference «person» is ambiguous.
It is required of me to return a TABLE (person integer). It works fine when I use SETOF integer but in this instance it doesn’t work. My other function recurse() returns a set of integers perfectly well.
CREATE OR REPLACE FUNCTION try(_group text) RETURNS TABLE (person integer) AS $$
DECLARE
_init_id integer;
_record integer;
BEGIN
SELECT id INTO _init_id FROM egroups WHERE name = _group;
FOR _record in SELECT person FROM egroupdata WHERE egroup IN (SELECT recurse(_init_id))
LOOP
RETURN NEXT;
END LOOP;
END;
$$ language plpgsql stable;
![]()
asked May 25, 2012 at 8:01
1
Ambiguous column references are due to there being more than one column available of the same name. In this case I guess it’s a quirk of returning a table. Try changing the query to:
SELECT egroupdata.person FROM egroupdata WHERE egroup IN (SELECT recurse(_init_id))
This will disambiguate the column reference.
answered May 25, 2012 at 8:39
Philip CoulingPhilip Couling
13k4 gold badges51 silver badges80 bronze badges
0
#sql #postgresql
Вопрос:
Пытаюсь упростить эту ВСТАВКУ и продолжаю получать эту неоднозначную ошибку ниже. Что я здесь делаю не так, нужен ли мне где-то псевдоним, которого мне не хватает?
<internal.PGError>: {
m: {
82: "scanRTEForColumn",
83: "ERROR",
86: "ERROR",
67: "42702",
77: "column reference "created_at" is ambiguous",
80: "3082",
70: "parse_relation.c",
76: "694",
},
}
Вот инструкция SQL, которую я использую:
INSERT INTO delivery_areas
SELECT
r.drn_id AS restaurant_drn_id,
'initial'::algorithm_name AS algorithm_name,
z.city_drn_id AS city_drn_id,
?::geometry AS delivery_area,
gen_random_uuid() AS drn_id,
?::timestamp AS created_at,
?::timestamp AS updated_at,
'custom'::delivery_area_type AS delivery_area_type
FROM restaurants r
JOIN neighborhood_zones nz ON (nz.hood_drn_id = r.hood_drn_id)
JOIN zones z ON (z.drn_id = nz.zone_drn_id)
WHERE r.drn_id = ?
GROUP BY restaurant_drn_id, algorithm_name, city_drn_id, created_at, updated_at, delivery_area_type
ON CONFLICT ON CONSTRAINT delivery_areas_pkey DO UPDATE
SET
delivery_area = EXCLUDED.delivery_area,
delivery_area_type = EXCLUDED.delivery_area_type,
updated_at = EXCLUDED.updated_at
RETURNING *
Создайте инструкции таблицы для областей доставки и ресторанов:
CREATE TYPE algorithm_name as ENUM ('initial');
CREATE TABLE delivery_areas (
restaurant_drn_id uuid NOT NULL,
algorithm_name algorithm_name NOT NULL DEFAULT 'initial',
city_drn_id uuid NOT NULL,
delivery_area geometry(MultiPolygon,4326) NOT NULL,
drn_id uuid NOT NULL DEFAULT gen_random_uuid(),
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL,
PRIMARY KEY (restaurant_drn_id, algorithm_name)
);
CREATE INDEX delivery_areas_algorithm_city_idx on delivery_areas (algorithm_name, city_drn_id);
CREATE INDEX delivery_areas_delivery_area_idx on delivery_areas USING gist(delivery_area);
ALTER TABLE delivery_areas ADD FOREIGN KEY (restaurant_drn_id) REFERENCES restaurants(drn_id);
CREATE TABLE restaurants (
drn_id uuid PRIMARY KEY,
hood_drn_id uuid NOT NULL,
delivery_range_delta_m int4 NOT NULL,
geo_lat double precision NOT NULL,
geo_long double precision NOT NULL,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);
Комментарии:
1. Таким образом, все столбцы в delivery_areas находятся в инструкции select. И поскольку я не могу добавить псевдоним в инструкцию INSERT INTO, что я упускаю?
2. Квалифицируйте все ссылки на ваши столбцы, как
delivery_areaи должно бытьdelivery_areas.delivery_area. Одна или несколько ссылок на ваши столбцы разрешаются двумя или более таблицами, и база данных просит вас устранить эту двусмысленность.3. Что
?::geometry AS delivery_area,должно быть ? Заполнитель для позиционного аргумента?4.
?::geometry AS delivery_area,действительно ли заполнитель для позиционного аргумента да5. Я добавил
delivery_areas.в качестве префикса перед всеми именами полей справа внутри выбора, но теперь выдает следующую ошибку:<internal.PGError>: { 77: "syntax error at or near "."", ... }
Ответ №1:
Обратите внимание, что в вашем GROUP BY предложении у вас есть ссылка на created_at :
GROUP BY restaurant_drn_id, algorithm_name, city_drn_id, created_at, updated_at, delivery_area_type
Но этот столбец есть в нескольких ваших таблицах.
Префикс этой ссылки на столбец с правильной таблицей, например:
GROUP BY restaurant_drn_id, algorithm_name, city_drn_id, delivery_areas.created_at, updated_at, delivery_area_type
Я только догадался, на какую таблицу вы хотели сослаться. Это устранит эту ошибку, но это может быть не та дата/отметка времени, по которой вы хотели сгруппироваться.
Вот пример проблемы и решения, а также подробные сведения, которые следует указывать при задании такого рода вопросов:
CREATE TABLE delivery_areas (
id int
, created_at timestamp
);
CREATE TABLE restaurants (
drn_id int
, created_at timestamp
);
CREATE TABLE othertbl (
id int
, created_at timestamp
);
-- The following generates an error:
INSERT INTO delivery_areas
SELECT r.drn_id AS restaurant_drn_id
, current_timestamp AS created_at
FROM restaurants r
JOIN othertbl o
ON o.id = r.drn_id
GROUP BY restaurant_drn_id, created_at
;
-- ERROR: column reference "created_at" is ambiguous
-- LINE 7: GROUP BY restaurant_drn_id, created_at
-- The following is one way to resolve the error:
INSERT INTO delivery_areas
SELECT r.drn_id AS restaurant_drn_id
, current_timestamp AS created_at
FROM restaurants r
JOIN othertbl o
ON o.id = r.drn_id
GROUP BY restaurant_drn_id, r.created_at
;
Обратите внимание на r.created_at . r является определителем, разрешающим двусмысленность.
Вот ссылка на тестовый случай:
Полный рабочий тестовый случай
Комментарии:
1. Итак, у вас здесь противоречивые советы, я должен использовать
r.created_atилиdelivery_areas.created_at? Если я использую последнее, я получу это:72: "There is an entry for table "delivery_areas", but it cannot be referenced from this part of the query.",2. @Уильямроуз Нет, нет. Вы посмотрели ссылку на скрипку, которую я предоставил?
r.created_atбыл в тестовом примере, который я создал. Я также сослался на ваш запрос, добавленный в начало ответа. Вы знаете, какуюcreated_atколонку вы хотелиGROUP BY?3. Ааа, хорошо. Да, я хотел бы сгруппироваться по
delivery_areasверсии4. @WilliamRose Идеально. Тогда мое предположение должно сработать, пока не будет найдена следующая проблема.
5. @WilliamRose
SELECTСписок определяет, что будет вставлено.tbl.created_atВGROUP BYтермины не вставляется, но используется для определения того, какие строки выбраны. Мы могли бы поболтать, если хочешь. Я не уверен, что вы понимаете такоеGROUP BYповедение.
Я попробовал следующий выбор:
SELECT (id,name) FROM v_groups vg
inner join people2v_groups p2vg on vg.id = p2vg.v_group_id
where p2vg.people_id =0;
и я получаю следующую ссылку на столбец с ошибкой id является неоднозначным.
Дело в том, что если я попробую то же самое SELECT но я только прошу name, а не для id Кроме того, это работает. Я новичок в этом, и, возможно, мне не хватает чего-то очевидного. Какие-либо предложения?
Благодарю.
4 ответы
Вам нужно имя / псевдоним таблицы в SELECT часть (возможно (vg.id, name)):
SELECT (vg.id, name) FROM v_groups vg
inner join people2v_groups p2vg on vg.id = p2vg.v_group_id
where p2vg.people_id =0;
ответ дан 04 дек ’20, 12:12
Я предполагаю, что ваша таблица p2vg также имеет поле id, в этом случае postgres не может найти, если идентификатор в SELECT относится к vg или p2vg.
вы должны использовать SELECT(vg.id,vg.name) убрать двусмысленность
ответ дан 05 мая ’17, 15:05
SELECT (vg.id, name) FROM v_groups vg
INNER JOIN people2v_groups p2vg ON vg.id = p2vg.v_group_id
WHERE p2vg.people_id = 0;
ответ дан 23 мар ’12, в 10:03
SELECT vg.id,
vg.name
FROM v_groups vg INNER JOIN
people2v_groups p2vg ON vg.id = p2vg.v_group_id
WHERE p2vg.people_id = 0;
Создан 25 сен.
Не тот ответ, который вы ищете? Просмотрите другие вопросы с метками
sql
postgresql
select
or задайте свой вопрос.
У меня есть эта простая тестовая функция в Postgres (в моей схеме test).
CREATE OR REPLACE FUNCTION test.func_001
(
par_id int
)
RETURNS TABLE
(
id int
)
AS
$BODY$
DECLARE
var_id int;
BEGIN
update test.item --- this is a table
set
id = 4
WHERE
id = 44;
return query
select 1000 as id;
END;
$BODY$
LANGUAGE plpgsql;
В таблице test.item есть единственный столбец идентификаторов.
Я получаю указанную ниже ошибку при попытке запустить функцию.
Query execution failed
Reason:
SQL Error [42702]: ERROR: column reference "id" is ambiguous
Detail: It could refer to either a PL/pgSQL variable or a table column.
Where: PL/pgSQL function test.func_001(integer) line 8 at SQL statement
Эта ошибка кажется странной, означает ли это, что Postgres обнаруживает конфликт / конфликт между столбцом test.item.id и столбцом id из возвращенной таблицы ?!
Как придешь? В этом нет никакого смысла.
Я не могу поверить в это, но я не вижу здесь других применений id.
Обратите внимание, что если я закомментирую только эту часть.
-- WHERE
-- id = 44;
Потом вдруг функция работает нормально.
Кажется, что Постгрес путает идентификатор в том, где
предложение с чем-то еще с именем id ?!
С чем?
Это совершенно нелогично и противоречит интуиции.
Может кто-нибудь объяснить?
Перейти к ответу
Данный вопрос помечен как решенный
Ответы
2
Существует конфликт имен между переменной id, которая определяется предложением RETURNS TABLE, и столбцом с тем же именем.
Подобные вещи вызывают проблемы во всех языках программирования, только PostgreSQL достаточно хорош, чтобы предупредить вас, а не делать что-то, что может быть не тем, что вы планировали.
Укажите ссылку на столбец следующим образом, чтобы устранить двусмысленность:
WHERE test.item.id = 44
Пункт FUNCTION fx() RETURNS TABLE(x int, y int, …) аналогичен пункту FUNCTION(OUT x int, OUT y int) RETURNS SETOF record. Итак, в вашем случае есть неявная переменная id, хотя вы не используете ее явно.
Дизайн PostgreSQL позволяет создавать строки без SQL.
CREATE OR REPLACE FUNCTION foo(a int)
RETURNS TABLE(b int, c int) AS $$
BEGIN
FOR i IN 1..a
LOOP
b := i; c := i * 10;
RETURN NEXT;
END LOOP;
END;
$$ LANGUAGE plpgsql;
См., Пожалуйста, документ следующий.
There is another way to declare a function as returning a set, which is to use the syntax RETURNS TABLE(columns). This is equivalent to using one or more OUT parameters plus marking the function as returning SETOF record (or SETOF a single output parameter’s type, as appropriate). This notation is specified in recent versions of the SQL standard, and thus may be more portable than using SETOF.
Другие вопросы по теме
я попробовал следующий выбор:
SELECT (id,name) FROM v_groups vg
inner join people2v_groups p2vg on vg.id = p2vg.v_group_id
where p2vg.people_id =0;
и я получаю следующую ссылку на столбец ошибок » id » неоднозначна.
дело в том , что если я попробую тот же выбор, но я прошу только (имя), а не id, он работает.
Я новичок в этом, и, возможно, я упускаю что-то очевидное. Есть предложения?
спасибо.
4 ответов
вам нужно имя таблицы / псевдоним в SELECT часть (возможно (vg.id, name)):
SELECT (vg.id,name) FROM v_groups vg
inner join people2v_groups p2vg on vg.id = p2vg.v_group_id
where p2vg.people_id =0;
Я полагаю, что ваша таблица p2vg также имеет поле id , в этом случае postgres не может найти, если id в SELECT относится к vg или p2vg.
вы должны использовать SELECT(vg.id,vg.name) удалить двусмысленность
SELECT (vg.id, name) FROM v_groups vg
INNER JOIN people2v_groups p2vg ON vg.id = p2vg.v_group_id
WHERE p2vg.people_id = 0;
SELECT vg.id,
vg.name
FROM v_groups vg INNER JOIN
people2v_groups p2vg ON vg.id = p2vg.v_group_id
WHERE p2vg.people_id = 0;