it-swarm.com.de

Rails 4-Abfrage eindeutig nach einzelnen Attributen

Das ist also mehr eine wichtige Frage als alles andere, als das, was ich versuche zu tun.

Ich habe drei Objekte, die ich Items nenne

<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
<Item id: 3, name: 'Book'>

Ich möchte eine Abfrage durchführen, die nur eines der eindeutigen "Namens" -Attribute zurückgibt.

So etwas wie Item.select('distinct(name), items.*')

Dies funktioniert jedoch nicht, es werden dennoch alle drei Elemente zurückgegeben.

Wie kann ich diese Abfrage so gestalten, dass sie nur Folgendes zurückgibt:

<Item id: 1, name: 'Book'>
<Item id: 2, name: 'Car'>
20
goddamnyouryan

Wenn Sie das gesamte Modell wiederherstellen möchten, aber dennoch die Eindeutigkeit beibehalten möchten, können Sie Folgendes verwenden:

Item.select('distinct on (name) *')

Ich habe dies nur mit einer Postgres-Datenbank getestet. Es kann mit MySQL funktionieren oder nicht.

30
BananaNeil

Bitte versuchen Sie dies:

Item.select('distinct name')
11
vee

Wenn Sie nur ein Array mit den Namen ohne die ID benötigen, können Sie Folgendes tun:

Item.pluck(:name).uniq

SQL-Abfrageergebnis:

#=> SELECT `items`.`name` FROM `items`

** bearbeiten **

Der uniqwird in dem Array von Datensätzen ausgeführt. Seien Sie vorsichtig, wenn Sie viele Aufzeichnungen erwarten. SQL Distinct ist viel schneller.

Wenn ja, benutze die Antwort von vee mit einem mapname__:

Item.select('distinct name').map(:name)

4
Frexuz

Ich kann noch keine Kommentare zu Beiträgen abgeben. Daher sollte dies eine weitere Antwort auf die Frage sein.

Falls noch jemand danach sucht, ist @ BananaNeils Antwort richtig. Das Einfügen von distinct in select hat bei mir jedoch nicht funktioniert (Rails 5.2.2). Das Trennen dieser beiden hat mein Problem behoben.

klass.where(
  # Your query or whatever
).distinct.select('on (attribute) *')
2
Oguzhan Ozdemir

In Rails 4 versuchen Sie Items.all.to_a.uniq { |item| item.name }

In Rails 3 solltest du nur Items.uniq_by { |item| item.name } machen können

Wenn Sie uniq für ein Array aufrufen, können Sie ihm einen Block übergeben, um festzulegen, wie die Eindeutigkeit bestimmt werden soll. In Rails 3 war es früher möglich, uniq_by zu verwenden, aber in Rails 4 war es veraltet. Daher habe ich eine Methode gefunden, die ActiveRecord-Relation einfach in ein Array zu konvertieren und uniq aufzurufen.

2
TalkativeTree

Das Folgende ist eine Rails-ORM-Abfrage, die mit allen neuesten Rails-Versionen Rails 5.X das gewünschte Ergebnis liefert.

@unique_values= []
Model.all.group_by(&:column_name).each do |key, val|
    if val.count == 1
      @unique_values << val
    else
      @unique_values << val.first
    end
end
0
Ankit Varshney

Für MySQL können Sie group mit ONLY_FULL_GROUP_BY disabled verwenden.

Item.group(:name).to_sql
=> "SELECT `items`.* FROM `items`  GROUP BY name"

Siehe Gibt es eine ANY_VALUE-Funktion für MySQL 5.6?

0
fangxing