Postgres: ошибка при использовании GROUP BY и ORDER (на heroku) - PullRequest
0 голосов
/ 14 ноября 2011

Я пытаюсь решить мою проблему с герою, которая, кажется, имеет проблему

К сожалению, что-то пошло не так.Мы получили уведомление об этой проблеме, и вскоре рассмотрим ее.

Есть ли у меня ошибка и как ее преодолеть?Как я могу интерпретировать эти журналы Heroku?

ActionView::Template::Error (PGError: ERROR:  column "microposts.created_at" must appear     in the GROUP BY clause or be used in an aggregate function
2011-11-14T17:33:07+00:00 app[web.1]: : SELECT category FROM "microposts" GROUP BY category ORDER BY microposts.created_at DESC):
2011-11-14T17:33:07+00:00 app[web.1]:     2: <% @categories= Micropost.select("category").group("category")%>
2011-11-14T17:33:07+00:00 app[web.1]:     3: <% unless @categories.nil? %>
2011-11-14T17:33:07+00:00 app[web.1]:     4: 
2011-11-14T17:33:07+00:00 app[web.1]:     5: <ul><% @categories.each do |category| %>
2011-11-14T17:33:07+00:00 app[web.1]:     6: <li><%= link_to category.category, :controller =>"microposts", :category => category.category, :method => 'category_list' %></li>
2011-11-14T17:33:07+00:00 app[web.1]:     7: <% end %>
2011-11-14T17:33:07+00:00 app[web.1]:     8: </ul>

модель микросообщений (добавлено новое)

 class Micropost < ActiveRecord::Base
belongs_to :users
default_scope :order => 'microposts.created_at DESC'


attr_accessible :title,:content,:category

validates :user_id, :presence => true
validates :title,    :presence => true,
                     :length => {:maximum =>500}                            
validates :content,  :presence => true,
                     :length => {:maximum =>3000}                           
validates :category, :presence => true
end

Ответы [ 2 ]

4 голосов
/ 14 ноября 2011

Ваша непосредственная проблема в том, что вы создаете недопустимый SQL для PostgreSQL:

SELECT category FROM "microposts" GROUP BY category ORDER BY microposts.created_at DESC

Ваш ORDER BY не соответствует остальной части вашего запроса. Вы не можете использовать столбец в сгруппированном запросе, если этот столбец также не сгруппирован или если столбец присутствует в статистической функции, это то, что означает сообщение об ошибке. Причина в том, что PostgreSQL не будет знать, какую строку created_at использовать, когда группа строк объединяется предложением GROUP BY; некоторые базы данных будут просто молча выбирать строку самостоятельно, PostgreSQL предпочитает быть строгим и хочет, чтобы вы удалили неоднозначность самостоятельно.

Попробуйте указать порядок самостоятельно:

@categories = Micropost.select("category").group("category").order("category")

Другой вариант - использовать DISTINCT вместо GROUP BY, чтобы избежать дублирования:

@categories = Micropost.select('DISTINCT(category)')

Кстати, вы действительно не должны делать подобные вещи в представлении, вы можете захотеть перенести это на свой контроллер.

Ваша настоящая проблема заключается в том, что вы разрабатываете поверх одной базы данных, а развертываете на другой. Я бы рекомендовал вам переключить среду разработки на PostgreSQL 8.3 (если вы развертываете в общую базу данных Heroku) или PostgreSQL 9.0 (если вы развертываете в выделенную базу данных).

2 голосов
/ 14 ноября 2011

Вы разрабатывали свое приложение на MySQL? Heroku не включает MySQL. Он использует postgreSQL. Посмотрите на этот вопрос здесь - PostgreSQL GROUP BY отличается от MySQL?

цитирую -

Полностью нестандартный GROUP BY MySQL можно эмулировать с помощью Postgres DISTINCT ON. Учтите это:

mysql:

  SELECT a,b,c,d,e FROM table GROUP BY a

Это доставляет 1 строку для каждого значения (которое, на самом деле, вы не знаете). Ну, на самом деле вы можете догадаться, потому что MySQL не знает о хеш-агрегатах, поэтому он, вероятно, будет использовать сортировку ... но он будет сортировать только по a, поэтому порядок строк может быть случайным. Если только он не использует многоколонный индекс вместо сортировки. Ну, во всяком случае, это не указано в запросе.

postgres:

   SELECT DISTINCT ON (a) a,b,c,d,e FROM table ORDER BY a,b,c

Это доставляет 1 строку на значение a, эта строка будет первой в сортировке в соответствии с ORDER BY, указанным в запросе. Простой.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...