powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Различное поведение запроса в зависимости от версии PG
10 сообщений из 10, страница 1 из 1
Различное поведение запроса в зависимости от версии PG
    #33758360
SOmni
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем доброго времени суток.
Есть PG 8.0.3, на котором запрос вида (про то, что нужно использовать where говорить не стоит, мой пример - упрощение запроса, в котором where не прокатит)

select id from <table_name> having id>0

работает на ура. Т.е. выдает все записи c id>0

Есть PG 8.1.2, в котором на этот же запрос выдается
ERROR: column "<table_name>.id" must appear in the GROUP BY clause or be used in an aggregate function

Вроде того, что если пишешь having, значит должен использовать и group by (или какую-то агрегирующую функцию). Но почему работает в первом случае? Может кто-нибудь просвятить в тонкостях работы having в данном случае?
...
Рейтинг: 0 / 0
Различное поведение запроса в зависимости от версии PG
    #33759212
ZemA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
думаю это был баг :) его исправили в 8.0.4
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
CREATE TABLE a
(
  id serial NOT NULL,
  aaa text NOT NULL,
  CONSTRAINT a_pkey PRIMARY KEY (id)
);

insert into a (aaa) values ('a');
insert into a (aaa) values ('b');
insert into a (aaa) values ('c');

andrey=# select version();
                              version
-------------------------------------------------------------------
 PostgreSQL  7 . 4  on i386-unknown-freebsd4. 8 , compiled by GCC  2 . 95 . 4 
( 1  row)

andrey=# select * from a having id = max(id);
ERROR:  column "a.id" must appear in the GROUP BY clause or be used in an aggregate         function

andrey=# select * from a group by id, aaa having id = max(id);
 id | aaa
----+-----
   3  | qqq
   2  | qqq
   1  | qqq
( 3  rows)

****************************************************

select version();
                              version
-------------------------------------------------------------------
"PostgreSQL 8.0.4 on i686-pc-mingw32, compiled by GCC gcc.exe (GCC) 3.2.3 (mingw special 20030504-1)"
( 1  rows)

select * from a having id = max(id);
ERROR:  column "a.id" must appear in the GROUP BY clause or be used in an aggregate function

select * from a group by id, aaa having id = max(id);
 id | aaa
----+-----
   3  | qqq
( 1  rows)

...
Рейтинг: 0 / 0
Различное поведение запроса в зависимости от версии PG
    #33759224
ZemA
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ошибся малость
ZemA
Код: plaintext
1.
2.
3.
insert into a (aaa) values ('a');
insert into a (aaa) values ('b');
insert into a (aaa) values ('c');

должно быть так
Код: plaintext
1.
2.
3.
insert into a (aaa) values ('qqq');
insert into a (aaa) values ('qqq');
insert into a (aaa) values ('qqq');
...
Рейтинг: 0 / 0
Различное поведение запроса в зависимости от версии PG
    #33759455
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOmniНо почему работает в первом случае? Может кто-нибудь просвятить в тонкостях работы having в данном случае?
ZemAдумаю это был баг :) его исправили в 8.0.4Это совершенно точно был баг. Причем не просто баг, а очень большой БАГ.
Ведь в ANSI-SQL весьма неоднозначно сказано - для фильтрации исходных данных при формировании результирующего датасета используется предложение WHERE, для ДОПОЛНИТЕЛЬНОЙ фильтрации результата работы агрегирующего запроса используется предложение HAVING. Без GROUP BY не может быть и HAVING.
Так что, сейчас в этом плане у PostgreSQL все в полном порядке - полное соответствие ANSI-стандарту :)
...
Рейтинг: 0 / 0
Различное поведение запроса в зависимости от версии PG
    #33759668
SOmni
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну хорошо. Это был баг. На самом деле запрос выглядит так:

select id, id_parent, _level_ from <table_name> connect by prior id=id_parent start with id=1 having _level_<2

Т.е. я выбирал все записи по иерархии уровня вложенности < 2
Куда тут можно впихнуть where я не знаю

А теперь так оно не работает и приходится делать что-то вроде:

select * from (select id, id_parent, _level_ from <table_name> connect by prior id=id_parent start with id=1) as sub where _level_ < 2

Есть более изящное решение?
...
Рейтинг: 0 / 0
Различное поведение запроса в зависимости от версии PG
    #33759697
SOmni
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Маленькое пояснение: _level_ - не поле в <table_name> - оно формируется connect_by-ем
...
Рейтинг: 0 / 0
Различное поведение запроса в зависимости от версии PG
    #33759750
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
SOmniНу хорошо. Это был баг. На самом деле запрос выглядит так:

select id, id_parent, _level_ from <table_name> connect by prior id=id_parent start with id=1 having _level_<2

Т.е. я выбирал все записи по иерархии уровня вложенности < 2
Куда тут можно впихнуть where я не знаю

А теперь так оно не работает и приходится делать что-то вроде:

select * from (select id, id_parent, _level_ from <table_name> connect by prior id=id_parent start with id=1) as sub where _level_ < 2

Есть более изящное решение?Грубо говоря ты выбирал все корни?
В данном конкретном слечае - запись с ID = 1.
Так зачем нужно было городить иерархический запрос для этих целей?

Не знаю как в PostgreSQL, но в Oracle вот такой запрос отрабатывает на ура:
Код: plaintext
1.
2.
3.
4.
5.
6.
select id, 
       parent_id, 
       level
  from t
 where level <=  2 
 connect by prior id = parent_id
 start with parent_id is null
Тут LEVEL аналог _LEVEL_
...
Рейтинг: 0 / 0
Различное поведение запроса в зависимости от версии PG
    #33759767
SOmni
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
"2" - не принципиально. Пусть будет 10. Всё равно, в PG where вставить в это место нельзя, получишь

ERROR: column "_level_" does not exist
...
Рейтинг: 0 / 0
Различное поведение запроса в зависимости от версии PG
    #33759786
Владимор Конев
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну попробуй ещё вот так:
Код: plaintext
1.
2.
3.
4.
5.
6.
select id, 
       parent_id, 
       level
  from t
 connect by prior id = parent_id 
              and level <=  2 
 start with parent_id is null
В Oracle также отлично отрабатывает, возвращая аналогичный результат
...
Рейтинг: 0 / 0
Различное поведение запроса в зависимости от версии PG
    #33759898
SOmni
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ех-х. Синтаксис connect by не регламентируется, а в PG и вовсе поддерживается энтузиастом :)
А потому:

ERROR: syntax error at or near "connect" at character 50
...
Рейтинг: 0 / 0
10 сообщений из 10, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Различное поведение запроса в зависимости от версии PG
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]