什么查询可以获取不同类别的特定用户的最新行?

时间:2015-09-06 18:22:15

标签: mysql ruby-on-rails activerecord

标题有点令人困惑。但是我有一个表来保存来自不同类别的用户的条目。因此,有类别ABC,用户可能在每个类别中都有多个条目。我需要一个SQL查询,它将获得每个类别的最新1条目(按created_at排序),希望在一个查询中。这是Rails,因此它可以是实际的SQL查询或ActiveRecord。

使用的列将是user_idcategory(只有ABC),created_atnotes(这是我需要的实际信息)。

3 个答案:

答案 0 :(得分:0)

试试这个(假设你i表中提到的所有列都存在):

to

答案 1 :(得分:0)

我们假设这里有一位用户(您的标题是for a specific user)。

基本上我们是在询问:

SELECT "entries".* FROM "entries"
LEFT JOIN entries e2 ON (
  entries.category=e2.category AND
  entries.created_at < e2.created_at AND
  entries.user_id = e2.user_id)
WHERE e2.id IS NULL AND entries.user_id=?

翻译成Rails:

user_id = @user.id
data = Entry.joins(%q{LEFT JOIN entries e2 ON (
  entries.category = e2.category AND
  entries.created_at < e2.created_at AND
  entries.user_id = e2.user_id
)}).where("e2.id IS NULL AND entries.user_id = ?", user_id)

如果您需要按类别分类的最后一个音符,请从res

获取
by_category = data.map{|e| [e.category, e.notes]}.to_h

注意您的要求是按created_at日期比较条目。我建议改用id。所以你可以这样写:

user_id = @user.id
data = Entry.joins(%q{LEFT JOIN entries e2 ON (
  entries.category = e2.category AND
  entries.id < e2.id AND
  entries.user_id = e2.user_id
)}).where("e2.id IS NULL AND entries.user_id = ?", user_id)

答案 2 :(得分:0)

以下是三种简单的SQL方法,还有更多,但我不确定MySQL支持窗口函数的程度等等。

1查找created_at是该user_id和类别的最大值的条目。如果两个条目具有相同的created_at作为两行,则将返回一个用户和类别的问题。

select *
from   entries
where  created_at = (
         select max(e.created_at)
         from   entries e
         where  e.user_id = entries.user_id and
                e.category = entries.category)

2通过created_at desc查找按行排序时该用户的第一个ID和类别的条目。如果两个条目与返回的一行具有相同的created_at是有问题的,那么您也可以通过id进行排序以实现此目的。

select *
from   entries
where  id = (
         select e.id
         from   entries e
         where  e.user_id = entries.user_id   and
                e.category = entries.category
         order by created_at desc
         limit    1)

3查找没有其他人为该用户和类别设置更大的created_at的条目。如果两个条目具有相同的created_at作为两行,则将返回一个用户和类别的问题。

 select *
 from   entries
 where  not exists (
          select e.id
          from   entries e
          where  e.user_id  = entries.user_id   and
                 e.category = entries.category  and
                 e.created_at > entries.created_at)

所有这些应该非常有效,但没有一个非常适合在ActiveRecord中表达。它们中的任何一个都可以将where子句表示为作用域,只是将它很好地封装在模型中,然后它就可以合并到一个关联中:

has_many :latest_category_entries, -> {merge(:latest_category)}, class_name => "Entry"

...所以你可以:

@user.latest_category_entries

User.includes(:latest_category_entries).each do |user|
  user.latest_category_entries.each do |entry|
    etc ...