Ошибка неоднозначная ссылка на столбец postgresql

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's user avatar

TylerH

20.7k65 gold badges73 silver badges98 bronze badges

asked Mar 22, 2012 at 11:09

Fofole's user avatar

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's user avatar

Yuri

4,1751 gold badge28 silver badges46 bronze badges

answered Mar 22, 2012 at 11:11

JScoobyCed's user avatar

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

Philip Kirkbride's user avatar

answered Mar 22, 2012 at 11:12

dweeves's user avatar

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's user avatar

user unknown

35.4k11 gold badges75 silver badges121 bronze badges

answered Mar 22, 2012 at 11:15

Janaki's user avatar

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;

Dmitry Bychenko's user avatar

answered Sep 25, 2017 at 6:55

Alex Mack's user avatar

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 SELECTed 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

Rafs's user avatar

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 поведение.

Я попробовал следующий выбор:

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

#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 поведение.

Понравилась статья? Поделить с друзьями:
  • Ошибка необъявленный идентификатор делфи
  • Ошибка неправильная конфигурация приложения
  • Ошибка необрабатываемое исключение автокад
  • Ошибка неполного деления
  • Ошибка нельзя установить свойство visible класса worksheet