Rails 3, ActiveRecord, PostgreSQL - команда ".uniq" не работает? - PullRequest
16 голосов
/ 18 марта 2012

У меня следующий запрос:

Article.joins(:themes => [:users]).where(["articles.user_id != ?", current_user.id]).order("Random()").limit(15).uniq

и выдает ошибку

PG::Error: ERROR:  for SELECT DISTINCT, ORDER BY expressions must appear in select list
LINE 1: ...s"."user_id" WHERE (articles.user_id != 1) ORDER BY Random() L...

Когда я обновляю исходный запрос до

Article.joins(:themes => [:users]).where(["articles.user_id != ?", current_user.id]).order("Random()").limit(15)#.uniq

так что ошибка ушла ... В MySQL .uniq работает, в PostgreSQL нет. Существуют ли альтернативы?

Ответы [ 4 ]

30 голосов
/ 13 июля 2012

В качестве ошибки указано for SELECT DISTINCT, ORDER BY expressions must appear in select list. Поэтому вы должны явно выбрать предложение, по которому вы заказываете.

Вот пример, он похож на ваш случай, но немного обобщен.

Article.select('articles.*, RANDOM()')
       .joins(:users)
       .where(:column => 'whatever')
       .order('Random()')
       .uniq
       .limit(15)

Итак, явно включите ваше предложение ORDER BY (в данном случае RANDOM()), используя .select(). Как показано выше, для того, чтобы ваш запрос возвращал атрибуты Article, вы также должны явно выбрать их.

Надеюсь, это поможет; удачи

2 голосов
/ 04 января 2013

Просто, чтобы обогатить поток дополнительными примерами, если у вас есть вложенные отношения в запросе, вы можете попробовать следующее утверждение:

Person.find(params[:id]).cars.select('cars.*, lower(cars.name)').order("lower(cars.name) ASC")

В данном примере вы запрашиваете все автомобили для данного человека, упорядоченные по названию модели (Audi, Ferrari, Porsche)

Я не думаю, что это лучший способ, но он может помочь в рассмотрении такого рода ситуаций, думая в объектах и ​​коллекциях, а не в реляционном (база данных).

Спасибо!

1 голос
/ 18 марта 2012

Я предполагаю, что метод .uniq переведен в предложение DISTINCT в SQL. PostgreSQL требователен (более требователен, чем MySQL) - все поля в списке выбора при использовании DISTINCT должны присутствовать в предложениях ORDER_BYGROUP_BY).

Немного неясно, что вы пытаетесь сделать (случайный порядок?). В дополнение к публикации полного отправленного SQL, если вы могли бы объяснить свою цель, это может быть полезно при поиске альтернативы.

0 голосов
/ 04 октября 2012

Я только что обновил свое 100% работающее и протестированное приложение с 3.1.1 до 3.2.7 и теперь имею ту же самую PG :: Ошибка.

Я использую Cancan ...

@users = User.accessible_by(current_ability).order('lname asc').uniq

Удаление .uniq решает проблему, и в этом простом запросе все равно не было необходимости.

Все еще просматривая заметки об изменениях между 3.1.1 и 3.2.7, чтобы увидеть, что привело к его поломке.

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