LINUX.ORG.RU

SQL запрос


0

0

Postgresql 8.1.9.
=> select * from (select * from infprog group by fm,im,ot,dtr) as fff;
ERROR: колонка "infprog.id" должна фигурировать в выражении GROUP BY или использоваться в агрегатной функции

infprog.id - тип serial.
Из таблицы infprog нужно выбрать уникальные записи по fm,im,ot,dtr.
Причем здесь id?


> => select * from (select * from infprog group by fm,im,ot,dtr) as fff;

а зачем внешний (первый) select ?

> Из таблицы infprog нужно выбрать уникальные записи по fm,im,ot,dtr. > Причем здесь id?

при том что ты не указал какие значения infprog.id тебе возвращать, без этого указания результат запроса будет не полным, с потерей части информации, так как на одну строку результата группировки может быть несколько разных значений infprog.id, например: (1 | a | b | c) (2 | a | b | c) - после группировки по (a, b, c) первое поле должно принимать одновременно два значения - [1, 2] что не укладывается в табличное представление данных :) ещё можно вместо [1, 2] возвращать первое попавшееся значение, так например поступает MySQL по умолчанию. если тебе нужно именно это - можешь написать так: select distinct on (fm,im,ot,dtr) * from infprog; только учти что когда ты выполнишь этот же запрос второй раз - содержимое не-distinct полей может быть другое - они же заполняются от балды :)

такое поведение - требование стандарта языка SQL (непомню от какого года) чтобы было по нормальному - нужно или добавить все возвращаемые поля в GROUP BY или выбирать только их, а не все *, либо использовать агрегатную функцию для получения их значения, например: select max(id), fm,im,ot,dtr from infprog group by fm,im,ot,dtr; - то есть ты явно указал что тебе возвращать только максимальное из значений id. именно это тебе и говорит СУБД в описании ошибки: 'колонка должна фигурировать в выражении GROUP BY или использоваться в агрегатной функции'

Eshkin_kot ★★
()
Ответ на: комментарий от Eshkin_kot

Спасибо за помощь!

> а зачем внешний (первый) select ?
Точная цель запроса подсчитать кол-во уникальных записей
по fm,im,ot,dtr. Упростил запрос, чтобы найти ошибку.

Так работает:
select count(*) from (select fm,im,ot,dtr from infprog group by fm,im,ot,dtr) as fff;




WinLin
() автор топика

Нет ну ты молодец. Если в таблице колонок больше, чем ты явно 
указал в GROUP а выборку делаешь полную *, то очевидно без функций
агреггирования у тебя будет ошибка. Никакого отношения ни к 
вложенному запросу ни к postgresql это не имеет. 
Почитай что ли sql. Да и вообще как ты себе представляешь 
такую выбоку? О_о

select * from infprog group by fm,im,ot,dtr
      ^^^ неверно.

select last(id), fm, im, ot, dtr from infprog group by fm,im,ot,dtr
      ^^^^^^^^^^ верно, если полей больше нету.

Anoxemian ★★★★★
()
Ответ на: комментарий от Anoxemian

select last(id), fm, im, ot, dtr from infprog group by fm,im,ot,dtr
^^^^^^^^^^ верно, если полей больше нету.

А если поля еще есть и они должны попасть в запрос?
Уже сейчас при конвертации данных нужно получить полностью
запись из 10 полей. Запись можно найти по fm,im,ot,dtr,max(dt_putev).

Делать три запроса с созданием дополнительных таблиц?

WinLin
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.