如何将自表子查询SQL转换为Rails的named_scope?

发布于 2024-10-31 13:47:45 字数 1442 浏览 4 评论 0原文

我使用的是 Rails 2.3.10,并且是 named_scope 的新版本。我正在处理一个 SQL,它检索特定事件的最后邀请列表。我想出了一个带有子查询的 SQL,看起来它可以做我想要的事情。我在想是否可以使用 named_scope 来做同样的事情,以便我可以将它与 find() 一起使用。

我有以下问题:

  1. 是否可以使用 named_scope 实现 SQL?
  2. 能否以一种优雅的方式使子选择不包含在:condition中?需要多个named_scope?
  3. named_scope 是什么样子的?
  4. find() 包含 name_scope 时,它​​会是什么样子?

SQL:

SELECT *
  FROM invitation inv1
  JOIN (
         SELECT event_id, user_id, MAX(invite_time) AS last_invite_time
           FROM invitation
          GROUP BY event_id, user_id
       ) AS last_invite ON
       inv1.event_id = last_invite.event_id AND
       inv1.user_id = last_invite.user_id AND
       inv1.invite_time = last_invite.last_invite_time

邀请数据:

event_id     user_id     invite_time       invite_reply_code
1            78          2011-02-01 15:21  1
2            78          2011-02-02 11:45  1
2            79          2011-02-02 11:50  1
2            79          2011-02-02 11:55  1
2            80          2011-02-02 11:50  1
2            80          2011-02-02 11:51  1

预期结果:

event_id     user_id     invite_time       invite_reply_code
2            78          2011-02-02 11:45  1
2            79          2011-02-02 11:55  1
2            80          2011-02-02 11:51  1

I'm using rails 2.3.10 and new to named_scope. I'm dealing with a SQL which retrieves a list of last invitations of a particular event. I came up with a SQL with subquery and it looks like it can do what I want. I'm thinking of is it possible to use named_scope to do the same thing so that I can make use of it with find().

I have the following questions:

  1. Is it possible to implement the SQL with named_scope?
  2. Can it be in a elegant way so that the sub-select is not included in the :condition?more than one named_scope needed?
  3. How do the named_scope(s) look like?
  4. How does the find() look like when it includes the name_scope(s)?

SQL:

SELECT *
  FROM invitation inv1
  JOIN (
         SELECT event_id, user_id, MAX(invite_time) AS last_invite_time
           FROM invitation
          GROUP BY event_id, user_id
       ) AS last_invite ON
       inv1.event_id = last_invite.event_id AND
       inv1.user_id = last_invite.user_id AND
       inv1.invite_time = last_invite.last_invite_time

Invitation data:

event_id     user_id     invite_time       invite_reply_code
1            78          2011-02-01 15:21  1
2            78          2011-02-02 11:45  1
2            79          2011-02-02 11:50  1
2            79          2011-02-02 11:55  1
2            80          2011-02-02 11:50  1
2            80          2011-02-02 11:51  1

Expected result:

event_id     user_id     invite_time       invite_reply_code
2            78          2011-02-02 11:45  1
2            79          2011-02-02 11:55  1
2            80          2011-02-02 11:51  1

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

注定孤独终老 2024-11-07 13:47:45

find 中的 :joins 选项可以采用一个字符串,它将直接粘贴到 SQL 中。要在那里获取你的 event_id ,你需要使用 lambda,所以你需要的是这样的东西:

named_scope :foo, lambda { |event_id|
  { :select => "oinv.*",
    :from => "invitation AS oinv"
    :joins => <<-SQL
      JOIN (
             SELECT event_id, user_id, MAX(invite_time) AS last_invite_time
               FROM invitation AS jinv
              GROUP BY event_id, user_id
           ) AS last_invite ON
           oinv.event_id       = last_invite.event_id AND
           oinv.user_id        = last_invite.user_id AND
           oinv.invite_time    = last_invite.last_invite_time
      SQL
    , :conditions => [ "oinv.event_id = ?", event_id ]
  }
}

这完全未经测试,但希望你能看到我在做什么,并且设置了你走在正确的道路上。

The :joins option in find can take a string, which it will just stick into the SQL. To get your event_id in there you will need to use a lambda, so something like this is what you're after:

named_scope :foo, lambda { |event_id|
  { :select => "oinv.*",
    :from => "invitation AS oinv"
    :joins => <<-SQL
      JOIN (
             SELECT event_id, user_id, MAX(invite_time) AS last_invite_time
               FROM invitation AS jinv
              GROUP BY event_id, user_id
           ) AS last_invite ON
           oinv.event_id       = last_invite.event_id AND
           oinv.user_id        = last_invite.user_id AND
           oinv.invite_time    = last_invite.last_invite_time
      SQL
    , :conditions => [ "oinv.event_id = ?", event_id ]
  }
}

This is totally untested, but hopefully you can see what I'm doing and this sets you on the right path.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文