I tried the following select:
SELECT (id,name) FROM v_groups vg
inner join people2v_groups p2vg on vg.id = p2vg.v_group_id
where p2vg.people_id =0;
and I get the following error column reference id
is ambiguous.
If I try the same SELECT
, but I only ask for name
and not for id
also, it works.
Any suggestions?
TylerH
20.7k65 gold badges73 silver badges98 bronze badges
asked Mar 22, 2012 at 11:09
2
You need the table name/alias in the SELECT
part (maybe (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;
Yuri
4,1751 gold badge28 silver badges46 bronze badges
answered Mar 22, 2012 at 11:11
JScoobyCedJScoobyCed
10.1k6 gold badges34 silver badges58 bronze badges
0
I suppose your p2vg table has also an id field , in that case , postgres cannot find if the id in the SELECT
refers to vg or p2vg.
you should use SELECT(vg.id,vg.name)
to remove ambiguity
answered Mar 22, 2012 at 11:12
dweevesdweeves
5,51522 silver badges28 bronze badges
1
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;
user unknown
35.4k11 gold badges75 silver badges121 bronze badges
answered Mar 22, 2012 at 11:15
JanakiJanaki
18512 bronze badges
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;
answered Sep 25, 2017 at 6:55
As a additional note: I got this error when I was using a CTE for a join resulting in an ambiguity. I was using the CTE in FROM
with an alias and despite prefixing the SELECT
ed column with the CTE’s alias, postgres would still produce this error on the prefixed column call. It was a bit trickier to discover as my query was long.
Hope it helps someone out there.
answered May 24, 2022 at 10:06
RafsRafs
6028 silver badges19 bronze badges
1
Вот так выглядит запрос
INSERT INTO users (balance, steamid, name, avatar)
VALUES (0, $1, $2, $3)
ON CONFLICT (steamid) DO
UPDATE SET name = $2, avatar = $3 WHERE steamid = $1;
Вот так выглядит таблица
CREATE TABLE users (
id BIGSERIAL NOT NULL PRIMARY KEY,
balance INTEGER NOT NULL,
steamid VARCHAR(50) NOT NULL UNIQUE,
name VARCHAR(50) NOT NULL,
avatar VARCHAR(100) NOT NULL,
tradelink_token VARCHAR(20),
tradelink_partner VARCHAR(20)
);
И вот такая ошибка:
error: неоднозначная ссылка на столбец «steamid»
#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
поведение.
#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;
Есть такой запрос:
SELECT * FROM ( SELECT t1.angles, t2.angles, row_number() over() as rn from orient t1, orient t2 limit 10) subquery WHERE rn > 5;
При запросе всех строк всё выполняется. Но как запросить только t1.angles или t2.angles ?
Т.е, такой запрос выдает ошибку:
SELECT t1.angles FROM ( SELECT t1.angles, t2.angles, row_number() over() as rn from orient t1, orient t2 limit 10) subquery WHERE rn >5;
ОШИБКА: таблица «t1» отсутствует в предложении FROM