Как получить различные значения с Арелем / реляционной алгеброй
-
01-10-2019 - |
Вопрос
Я делаю все возможное, чтобы согнуть мозг вокруг Ареля и реляционной алгебры за ним, но как представлять SELECT DISTINCT
последовательно усугубляет мое понимание. Может кто-нибудь объяснить, как Арель:
SELECT DISTINCT title FROM posts;
Большое спасибо!
Решение
Post.select('DISTINCT title')
Обновление 1:
Во время поста это не было доступно в Ареле. В наши дни ActiveRecord :: Querymethods имеет uniq
метод (http://apidock.com/rails/activerecord/Querymethods/uniq.), так что вы хотите:
Post.select(:title).uniq
Обновление 2:Похоже, Arel теперь поддерживает это поведение. @maerics имеет правильный ответ. Я бы удалил это, если это не был принятым ответом.
Другие советы
Использование Pure Arel (не Rails / Activerecord) Существует «отличный» метод:
Arel::VERSION # => '3.0.2'
posts = Arel::Table.new(:posts)
posts.project(posts[:title])
posts.distinct
posts.to_sql # => 'SELECT DISTINCT "posts"."title" FROM "posts"'
Любопытно, что «отчетливый» метод не является церемонтируемым, на другой методы AREL.
Способ сделать это:
t = Arel::Table.new(:foo)
count_distinct = t[:field].count(true)
count_distinct.to_sql # => "COUNT(DISTINCT `foo`.`field`)"
Предыдущий ответ - это направляющий путь, нет? Не олель путь.
Это работает для Арель 1.x:
posts = Table(:posts)
posts.project(Arel::Distinct.new(posts[:title]))
Я думаю, что есть еще один «более правильный» способ сделать это через API, но я еще не разобрался.
Если вы делаете это, используя объем:
scope :recent, lambda {|count|
select("DISTINCT posts.*").
joins(:whatever).
limit(count).
order("posts.updated_at DESC")
}
Поскольку Arel всегда использует набор в своей работе, повторяющиеся результаты строки будут удалены автоматически. Просто используйте нормальную работу проекта (PHI).