Ruby on Rails ActiveRecord: получить уникальные записи по атрибуту 1, упорядоченные по атрибуту 2 [дублировать]

Говорят, что ваш list является List объектов, не указанных. Это значит, что Java не знает, какие объекты находятся внутри списка. Затем, когда вы хотите итерировать список, вы должны использовать каждый элемент, чтобы иметь доступ к свойствам этого элемента (в данном случае, String).

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

private static List<String> list = new ArrayList<String>();
21
задан Tintin81 22 January 2014 в 19:04
поделиться

4 ответа

Postgres

В Postgres это может быть достигнуто с помощью следующего запроса.

SELECT DISTINCT ON ("group") * FROM projects
ORDER BY "group", date DESC, id DESC

Поскольку столбец date может быть не уникальным здесь, я добавил дополнительный ORDER BY на id DESC, чтобы разорвать связь в пользу записи с более высоким идентификатором, в случае, если две записи в группе имеют одинаковую дату. Вместо этого вы можете использовать другой столбец, например, дату / время последнего обновления или так, что зависит от вашего варианта использования.

При переходе к ActiveRecord, к сожалению, нет API для DISTINCT ON, но мы можем по-прежнему использовать простой SQL с select:

Project.select('DISTINCT ON ("group") *').order(:group, date: :desc, id: :desc)

или если вы предпочитаете использовать AREL вместо наличия необработанного SQL:

p = Project.arel_table
Project.find_by_sql(
  p.project(p[Arel.star])
   .distinct_on(p[:group])
   .order(p[:group], p[:date].desc, p[:id].desc)
)

MySQL

Для другие базы данных, такие как MySQL, к сожалению, не так удобны. Существует множество доступных решений, см., Например, этот ответ .

41
ответ дан Patrick Oscity 21 August 2018 в 17:14
поделиться

Что-то вроде этого?

Project.select(:group).map(&:group).uniq.each do |grp|
  puts Project.where(group: grp).order("date DESC").last
end

Это будет проходить через все ваши группы и идентифицировать уникальные. В вашем примере он должен вернуть ["1", "2"]. Затем он выполняет итерацию по этому массиву и выбирает последний проект с идентификатором группы 1 и последним проектом с идентификатором группы 2.

** Обновление **

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

-6
ответ дан AdamT 21 August 2018 в 17:14
поделиться
  • 1
    это также будет извлекать все записи из базы данных, затем отфильтровывать их в памяти и, наконец, делать другой запрос для каждой группы. – Patrick Oscity 22 January 2014 в 19:38

Это работает для меня

ids = Message.select("MAX(id) AS id").group(:column_name).collect(&:id)
@result = Message.order("created_at DESC").where(:id => ids)
0
ответ дан Navid Farjad 21 August 2018 в 17:14
поделиться
Project.where(:group => "1", :date => "2014-01-01").last

.last - это то, что вы ищете.

-10
ответ дан nzajt 21 August 2018 в 17:14
поделиться
Другие вопросы по тегам:

Похожие вопросы: