Как получить разные значения с помощью ареля / реляционной алгебры - PullRequest
11 голосов
/ 29 июня 2010

Я делаю все возможное, чтобы обернуть мой мозг вокруг ареля и реляционной алгебры, стоящей за ним, но как изобразить SELECT DISTINCT постоянно ускользает от моего понимания. Может кто-нибудь объяснить, как это сделать:

SELECT DISTINCT title FROM posts; 

Большое спасибо!

Ответы [ 6 ]

13 голосов
/ 19 сентября 2012

Используя чистый 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.

8 голосов
/ 30 мая 2014

Арель способ сделать это:

t = Arel::Table.new(:foo)
count_distinct = t[:field].count(true)
count_distinct.to_sql # => "COUNT(DISTINCT `foo`.`field`)"
6 голосов
/ 19 августа 2010

Предыдущий ответ - путь Rails, нет?Не путь Ареля.

Это работает для 1.x:

posts = Table(:posts)
posts.project(Arel::Distinct.new(posts[:title]))

Я думаю, есть еще один "более правильный" способ сделать это черезAPI, но я еще не понял этого.

3 голосов
/ 01 февраля 2011

Если вы делаете это, используя область действия:

  scope :recent, lambda {|count|
    select("DISTINCT posts.*").
    joins(:whatever).
    limit(count).
    order("posts.updated_at DESC")
  }
1 голос
/ 29 июня 2010

Post.select('DISTINCT title')

Обновление 1:

На момент публикации это не было доступно в Ареле. В наши дни ActiveRecord :: QueryMethods имеет метод uniq (http://apidock.com/rails/ActiveRecord/QueryMethods/uniq),, поэтому вам нужно:

Post.select(:title).uniq

Обновление 2: Похоже, Арель теперь поддерживает это поведение. У @maerics правильный ответ. Я бы удалил это, если бы это был не принятый ответ.

0 голосов
/ 25 марта 2012

Поскольку AREL всегда использует SET в своей работе, дублированные результаты строки будут автоматически удалены. Просто используйте обычную операцию Project (Phi).

...