Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Различное поведение запроса в зависимости от версии PG / 10 сообщений из 10, страница 1 из 1
29.05.2006, 14:54
    #33758360
SOmni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
Всем доброго времени суток.
Есть 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
29.05.2006, 20:07
    #33759212
ZemA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
думаю это был баг :) его исправили в 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
29.05.2006, 20:21
    #33759224
ZemA
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
ошибся малость
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
30.05.2006, 06:04
    #33759455
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
SOmniНо почему работает в первом случае? Может кто-нибудь просвятить в тонкостях работы having в данном случае?
ZemAдумаю это был баг :) его исправили в 8.0.4Это совершенно точно был баг. Причем не просто баг, а очень большой БАГ.
Ведь в ANSI-SQL весьма неоднозначно сказано - для фильтрации исходных данных при формировании результирующего датасета используется предложение WHERE, для ДОПОЛНИТЕЛЬНОЙ фильтрации результата работы агрегирующего запроса используется предложение HAVING. Без GROUP BY не может быть и HAVING.
Так что, сейчас в этом плане у PostgreSQL все в полном порядке - полное соответствие ANSI-стандарту :)
...
Рейтинг: 0 / 0
30.05.2006, 09:55
    #33759668
SOmni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
Ну хорошо. Это был баг. На самом деле запрос выглядит так:

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
30.05.2006, 10:07
    #33759697
SOmni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
Маленькое пояснение: _level_ - не поле в <table_name> - оно формируется connect_by-ем
...
Рейтинг: 0 / 0
30.05.2006, 10:27
    #33759750
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
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
30.05.2006, 10:31
    #33759767
SOmni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
"2" - не принципиально. Пусть будет 10. Всё равно, в PG where вставить в это место нельзя, получишь

ERROR: column "_level_" does not exist
...
Рейтинг: 0 / 0
30.05.2006, 10:38
    #33759786
Владимор Конев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
Ну попробуй ещё вот так:
Код: 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
30.05.2006, 11:11
    #33759898
SOmni
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Различное поведение запроса в зависимости от версии PG
Ех-х. Синтаксис connect by не регламентируется, а в PG и вовсе поддерживается энтузиастом :)
А потому:

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


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