2016-05-22 14 views
5
| id | user_id | created_at (datetime) | 
| 1  | 1  | 17 May 2016 10:31:34 | 
| 2  | 1  | 17 May 2016 12:41:54 | 
| 3  | 2  | 18 May 2016 01:13:57 | 
| 4  | 1  | 19 May 2016 07:21:24 | 
| 5  | 2  | 20 May 2016 11:23:21 | 
| 6  | 1  | 21 May 2016 03:41:29 | 

Jak mogę uzyskać wynik unikatowego i najnowszego utworzonego rekordu user_id, który będzie rekordem 5 i 6 w powyższym przypadku?Wybierz unikalny rekord z najnowszą datą utworzenia

Co Próbowałem tak daleko

tej pory staram się używać group_by powrócić hash takiego:

Table.all.group_by(&:user_id) 

#{1 => [record 1, record 2, record 4, record 6], etc} 

i wybrać rekord z maksymalnym terminem od niego? Dzięki.

Zaktualizowane rozwiązanie

Dzięki Gordon odpowiedź, używam find_by_sql używać surowego kwerendy SQL w ROR.

@table = Table.find_by_sql("Select distinct on (user_id) * 
          From tables 
          Order by user_id, created_at desc") 

#To include eager loading with find_by_sql, we can add this 

ActiveRecord::Associations::Preloader.new.preload(@table, :user) 
+0

Mam noob, ale pomysłem byłoby spróbować: Model.find (: id) .order (: created_at) .last, ale działa tylko dla jednego user_id. Może dodanie plucka, takiego jak: Model.find (: id) .order (: created_at) .uniq.pluck (: id_użytkownika) .last – Maxence

+0

Właściwie myślę, że pluck nie działa. może używając: Model.order (: created_at) .where (: user_id ...). last i zapętlać? – Maxence

+0

Dzięki! Na koniec wybrałem odpowiedź "odrębna od", która może uzyskać unikalny identyfikator użytkownika. – pyfl88

Odpowiedz

3

W Postrgres, można użyć DISTINCT ON:

SELECT DISTINCT ON (user_id) * 
FROM tables 
ORDER BY user_id, created_at DESC; 

nie jestem pewien, jak to wyrazić w Ruby.

+0

Proszę mnie poprawić, jeśli się mylę, ale można to wyrazić w składni MySQL jako: 'SELECT created_at FROM tables GROUP BY id_użytkownika ORDER BY created_at DESC;' –

+0

Problem polega na tym, że nie można zamawiać tylko przez 'created_at' w Postgresie "identyfikator_użytkownika" również powinien być częścią klucza sortowania. –

+0

@philpirozhkov. . . Absolutnie nie. Jeśli masz pytanie dotyczące MySQL, powinieneś zbadać odpowiedzi w tej bazie danych lub zadać je samemu sobie. –

-2

Jeśli chcesz ostatni rekord:

Table.order(:created_at).last 

Jeśli chcesz ostatnie 2 rekordy:

Table.order(:created_at).last(2) 
0

1) Wyciąg unikalnych użytkowników tworzyć tabelę

Table.all.uniq(:user_id) 

2) Znajdź wszystkie rekordy każdego użytkownika.

Table.all.uniq(:user_id).each {|_user_id| Table.where(user_id: _user_id)} 

3) Wybierz najnowsza stworzona

Table.all.uniq(:user_id).each {|_user_id| Table.where(user_id: _user_id).order(:created_at).last.created_at} 

4) return result w postaci: [[id, user_id], [id, user_id] ...]

Table.all.uniq(:user_id).map{|_user_id| [Table.where(user_id: _user_id).order(:created_at).last.id, _user_id]} 

należy zwrócić [[6,1] [2,5]]

+0

Czy bit "all.uniq" nie ryzykuje wymknięcia się z ostatnio utworzonych rekordów? – Maxence

+0

@Maxence Zaktualizowałem odpowiedź. Chyba nie, ponieważ pyfl88 potrzebuje najnowszego created_at dla ** each ** id_użytkownika. Otrzymując wszystkie unikalne user_ids, nie wykluczam niczego. W jego przykładzie są tylko dwa unikalne identyfikatory ** [1,2] **, niż przechodzę przez rekordy zawierające te id_użytkownika. –

0
Table 
    .select('user_id, MAX(created_at) AS created_at') 
    .group(:user_id) 
    .order('created_at DESC') 

Powiadomienie created_at jest przekazywane jako ciąg w wywołaniu order, ponieważ jest wynikiem funkcji agregującej, a nie wartości kolumny.

Powiązane problemy