PostgreSQL
 sql >> база данни >  >> RDS >> PostgreSQL

Rails 3.1 с PostgreSQL:GROUP BY трябва да се използва в агрегатна функция

Sql, генериран от израза, не е валидна заявка, вие групирате по user_id и избиране на много други полета въз основа на това, но без да казва на DB как трябва да агрегира другите файлове. Например, ако вашите данни изглеждат така:

a  | b
---|---
1  | 1
1  | 2
2  | 3

Сега, когато поискате от db да групира по a и също връща b, то не знае как да агрегира стойности 1,2 . Трябва да кажете дали трябва да изберете мин., макс., средно, сума или нещо друго. Точно докато пишех отговора, имаше два отговора, които биха могли да обяснят всичко това по-добре.

Във вашия случай на употреба обаче мисля, че не искате група от на ниво db. Тъй като има само 10 изкуства, можете да ги групирате във вашето приложение. Все пак не използвайте този метод с хиляди изкуства:

 arts = Art.all(:order => "created_at desc", :limit => 10)
 grouped_arts = arts.group_by {|art| art.user_id}
 # now you have a hash with following structure in grouped_arts
 # { 
 #    user_id1 => [art1, art4],
 #    user_id2 => [art3],
 #    user_id3 => [art5],
 #    ....
 # }

РЕДАКТИРАНЕ: Изберете latest_arts, но само едно изкуство на потребител

Само за да ви дам представа за sql (не съм го тествал, тъй като нямам RDBMS инсталиран на моята система)

SELECT arts.* FROM arts
WHERE (arts.user_id, arts.created_at) IN 
  (SELECT user_id, MAX(created_at) FROM arts
     GROUP BY user_id
     ORDER BY MAX(created_at) DESC
     LIMIT 10)
ORDER BY created_at DESC
LIMIT 10

Това решение се основава на практическото предположение, че няма две изкуства за един и същ потребител, които могат да имат една и съща най-висока created_at, но може да е погрешно, ако импортирате или програмно създавате голяма част от изкуства. Ако предположението не е вярно, sql може да стане по-измислен.

РЕДАКТИРАНЕ: Опитайте се да промените заявката на Arel:

Art.where("(arts.user_id, arts.created_at) IN 
             (SELECT user_id, MAX(created_at) FROM arts
                GROUP BY user_id
                ORDER BY MAX(created_at) DESC
                LIMIT 10)").
    order("created_at DESC").
    page(params[:page]).
    per(params[:per])


  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да принудим оценка на подзаявката преди присъединяване/натискане надолу към чужд сървър

  2. Има ли начин да се зададе време на изтичане, след което запис на данни се изтрива автоматично в PostgreSQL?

  3. Как да активирам функцията за профилиране на PostgreSQL?

  4. Внедрете Postgres11 в Elastic Beanstalk - Изисква /etc/redhat-release

  5. Как да напишете заявка, нечувствителна към главните букви и за MySQL, и за Postgres?