PostgreSQL и GROUP BY

52 views
Skip to first unread message

Alexander Negoda

unread,
Jul 15, 2010, 5:30:24 AM7/15/10
to rugr...@googlegroups.com
Всем привет.
Никак не могу побороть следующую проблему.
Нужно выбрать из postgresql-базы компании, входящие в определённые отрасли. Компании могут входить в несколько отраслей. Нужно выбрать так, чтобы если компания встречается несколько раз, то в результате выборки она была только один раз.
Решается эта задача с помощью GROUP BY. В mysql-базе всё работает без проблем. Достаточно в запросе сделать GROUP BY id.
С postgresql это делается по-другому - нужно перечислить все поля таблицы: GROUP BY company.id, company.name, company.description и т.д.

Покуда проект был на рубирельсах, это работало без проблем. Сейчас переношу на grails и никак не могу сделать GROUP BY. Пробую в консоли вот так:

Business.findAll("from Business as b left join fetch b.branches as br where br.id in (:branches) group by  br.id, br.name, br.description,    b.address,  b.id, b.phones, b.email, b.description, b.name",
              [branches:[3,5,8]],
              [offset: 0, sort: "name", order: "ASC", max:10] )


В ответ:
ERROR: column "branches1_.business_id" must appear in the GROUP BY clause or be used in an aggregate function

И здесь я не пойму что делать. Поля такого branches1_.business_id нет. Компании связаны с отраслями много-ко-многим.

class Business {
    static mapping = {
         table 'businesses'
         id generator:'identity', column:'id'
         branches column:'business_id',joinTable:'branches_businesses'
         address column:'address_id'
    }

    Integer id
    String name
    String description
    String phones
    String email

    Address address

    static belongsTo = Branch

    static hasMany = [ branches : Branch ]
}

class Branch {
    static mapping = {
         table 'branches'
         id generator:'identity', column:'id'
         businesses column:'branch_id',joinTable:'branches_businesses'
   }

    Integer id
    String name
    String description

    static hasMany = [ businesses : Business ]
}

Как вариант, я мог-бы из результата запроса убрать повторы, но мне также нужно узнать кол-во совпадений. Например, найдено по запросу 150 компаний, но если убрать повторы (group by ) останется 140. Клиенту нужно отдать 10 из 140-а и само количество (140):
businesses = [b1,b2,b3....] 
total=140

Выбирать в память без group by и убирать повторы приложении как-то не рационально. Без group by другого решения не вижу.
Буду благодарен за советы.

Alexander Negoda

unread,
Jul 15, 2010, 6:29:19 AM7/15/10
to rugr...@googlegroups.com
Не знаю, что и думать...

Если в запросе указывать max, то результаты фильтруются даже без GROUP BY:

Business.findAll("from Business as b left join fetch b.branches as br where br.id in (:branches)",
              [branches:[3,5]],
              [offset: 0, sort: "name", order: "DESC", max:1000] )

Получаю 275 строк - здесь все строки уникальны, даже если компания встречается в нескольких отраслях.

Business.findAll("from Business as b left join fetch b.branches as br where br.id in (:branches)",
              [branches:[3,5]],
              [offset: 0, sort: "name", order: "DESC"] )

Получаю 325 строк - здесь встречаются повторы.

Кто-нибудь знает, почему так?
Reply all
Reply to author
Forward
0 new messages