雖然在回答諸如「每天最近發佈的帖子是什麼時候」這樣的問題時,SQL非常簡單。當你問「每天最近的帖子是什麼?」時,它並不是非常直接的。
如果不使用子SELECT(或多個SQL語句),則無法每天檢索最新的Post。這可能會爲你(使用Post.find_by_sql或類似)工作:
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
上面的SQL語句應該是足夠如果你可以肯定的是,兩個職位將不會有在created_at列中的值相同。如果你不能保證創建列的唯一性,那麼你需要在Ruby中過濾出重複項(這應該不是太低效,因爲大概你會在列表中循環),否則你需要執行N +1 SQL語句。 (實際上你可以做每行選擇,但AFAIK與N + 1 SQL語句一樣低效。)
這裏是你如何可以刪除重複而循環:
last_post = nil
posts.each do |post|
unless post.just_day == last_past.try(:just_day)
# Do stuff
last_post = post
end
end
這就是說,你可以把它很好地只用紅寶石/ ActiveRecord的寫,如果你有足夠的幾天,一個SELECT每天ISN」牛逼太糟糕了:
days = Post.group("date(date)")
posts = days.each { |day| Post.order('created DESC').where("date(day) = ?", day) }
如果您正在使用分頁(說每頁10個項目),那麼這將需要爲每個頁面11個SQL語句。不是想法,但簡單可能值得效率低下。老實說,如果你希望這個查詢既經常運行,又有相當大的數據集,那麼我建議你添加一個名爲most_recent的布爾列。過去幾天的最後一篇文章不會改變。你只需要擔心從今天開始的帖子。只需設置一個cron作業即可在一天結束後運行幾分鐘以更新最後一天的值。如果你想要更新的東西,你可以每5分鐘運行一次cron作業。或者,如果你需要實時的話,那麼添加一個after_save回調函數,將當前帖子以外的所有帖子的most_recent設置爲false。
這個問題是類似的:MySQL: Getting highest score for a user
「數組...按日期分組」 - 這是沒有意義的。你想達到什麼目的?你能按日期(日期)訂購嗎? – DanSingerman 2010-08-18 13:01:18
除MySQL以外的任何數據庫都將拒絕非法SQL。數據庫不會猜測你今天會想要什麼結果,db只能在所有情況下得到所有正確的結果。在MySQL中使用ONLY_FULL_GROUP_BY,以上查詢也將被MySQL拒絕。 – 2010-08-18 13:37:04
嗨丹 - 我試圖獲得Post對象數組,但我只想在任何給定日期(當天的最新Post)檢索一個Post。 – digitalfrost 2010-08-21 15:55:21