Chociaż SQL jest dość prosty, jeśli chodzi o udzielanie odpowiedzi na pytania typu "kiedy ostatni post był na każdy dzień?" NIE jest to bardzo proste, gdy pytasz "który był najnowszym postem na każdy dzień?"
Nie można pobrać najnowszego wpisu na każdy dzień bez użycia podrzędnego SELECT (lub wielu instrukcji SQL). To może pracować dla Ciebie (wykorzystanie Post.find_by_sql lub podobny):
SELECT P.*, M.just_day, M.max_created_at
FROM posts P
JOIN (
SELECT date(P2.date) AS just_day, MAX(P2.created_at) AS max_created_at
FROM posts P2
P.location_id='12345' AND P.published=true
GROUP BY date(P2.date)
) AS M
ON AND M.max_created_at = P.created_at
WHERE P.location_id='12345' AND P.published=true
Powyższe oświadczenie SQL powinien być wystarczająco jeśli można mieć pewność, że dwa posty nie będą miały taką samą wartość w kolumnie created_at. Jeśli nie możesz zagwarantować unikalności w kolumnie utworzonej w kolumnie, musisz albo odfiltrować duplikaty w Ruby (które nie powinny być zbyt nieefektywne, ponieważ prawdopodobnie i tak będziesz pętlą nad listą) lub będziesz musiał zrobić N +1 instrukcje SQL. (Właściwie można wykonywać wybory w wierszach, ale AFAIK, które są tak samo nieefektywne jak instrukcje SQL N + 1.)
Oto w jaki sposób można usunąć duplikaty podczas zapętlenie:
last_post = nil
posts.each do |post|
unless post.just_day == last_past.try(:just_day)
# Do stuff
last_post = post
end
end
Powiedział, że można ją napisać ładnie tylko z Ruby/ActiveRecord, jeśli masz wystarczająco dużo kilka dni, że SELECT dla każdego dnia ISN” t tak źle:
days = Post.group("date(date)")
posts = days.each { |day| Post.order('created DESC').where("date(day) = ?", day) }
Jeśli używasz paginacji (powiedzmy 10 pozycji na stronie), to będzie wymagało 11 SQL dla każdej strony. Nie pomysły, ale prostota może być warta nieskuteczności.
Szczerze mówiąc, jeśli spodziewasz się, że zapytanie będzie zarówno uruchamiane często, jak i z dość dużym zbiorem danych, proponuję dodać kolumnę boolowską o nazwie most_recent. Ostatni post z ostatnich dni nie zmieni się. Musisz tylko martwić się o posty z dzisiaj. Wystarczy skonfigurować zadanie cron, aby uruchomić kilka minut po zakończeniu dnia, aby zaktualizować wartość ostatniego dnia. Jeśli chcesz czegoś bardziej aktualnego, możesz uruchomić zadanie cron co 5 minut. Lub jeśli potrzebujesz w czasie rzeczywistym, a następnie dodaj callback after_save, aby ustawić most_recent na false dla wszystkich dzisiejszych postów, które nie są bieżącym postem.
To pytanie jest podobne: MySQL: Getting highest score for a user
Określenie "array ... pogrupowane według daty" - to nie ma sensu. Co próbujesz osiągnąć? Czy możesz po prostu zamówić według daty (daty)? – DanSingerman
Każda baza danych, z wyjątkiem MySQL, odrzuci nielegalny SQL. Bazy danych nie zgadują, jakie wyniki chcesz dzisiaj, db powinny uzyskać tylko poprawne wyniki we wszystkich sytuacjach. Użyj ONLY_FULL_GROUP_BY w MySQL, a powyższe zapytanie również zostanie odrzucone przez MySQL. –
Witaj Dan - Próbuję uzyskać tablicę obiektów Post, ale chcę pobrać tylko jeden post dla danego dnia (najnowszy post dla tego dnia). – digitalfrost