Rails + MySQL GROUP BY并从GROUP

时间:2015-06-19 06:09:41

标签: mysql ruby-on-rails group-by

我有这两个模型users& jobs以这种方式设计关系。

用户

+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
|  4 |
+----+

作业

+-----+---------+------------------+---------------------+
| id  | user_id | receiver_user_id | updated_at          |
+-----+---------+------------------+---------------------+
| 111 |       1 |                2 | 2015-06-18 08:23:55 |
| 112 |       1 |                2 | 2015-06-18 08:28:40 |
| 113 |       1 |                3 | 2015-06-18 08:37:32 |
| 114 |       1 |                3 | 2015-06-18 08:37:51 |
| 115 |       2 |                1 | 2015-06-18 09:28:49 |
| 116 |       1 |                4 | 2015-06-18 09:29:58 |
| 117 |       1 |                4 | 2015-06-18 10:20:29 |
+-----+---------+------------------+---------------------+

user.rb

has_many :sent_jobs, :class_name => "Job", :foreign_key => :user_id

has_many :received_jobs, :class_name => "Job", :foreign_key => :receiver_user_id

def jobs_sent_and_received
  Job.where("user_id = ? OR receiver_user_id = ?", self.id, self.id)
end

(这是我能想到的最佳方式。如果有办法将jobs_sent_and_received合并到一个has_many关系,那就更好了。

但是我的问题是当User => 1搜索工作(发送/接收)时,我需要从其他用户那里获得最后一份工作。

到目前为止,这是我尝试过的:

job_ids = current_user.jobs_sent_and_received.select([:id, "MAX(updated_at)"]).group([:user_id, :receiver_user_id]).collect(&:id)

@jobs = Job.order("updated_at DESC").where(:id => job_ids)

通过这种方法,我仍然可以从user id => 2得到2条记录为job.id 111, 115但我在结果集中只需要job.id => 115

希望我的问题很明确。感谢任何帮助。感谢

结果(当前)

SELECT id, MAX(updated_at) FROM `jobs` WHERE (user_id = 1 OR receiver_user_id = 1) GROUP BY user_id, receiver_user_id;
+-----+---------------------+
| id  | MAX(updated_at)     |
+-----+---------------------+
| 111 | 2015-06-18 08:28:40 |
| 113 | 2015-06-18 08:37:51 |
| 116 | 2015-06-18 10:20:29 |
| 115 | 2015-06-18 09:28:49 |
+-----+---------------------+

   SELECT `jobs`.* FROM `jobs` WHERE `jobs`.`id` IN (111, 113, 116, 115) ORDER BY updated_at DESC LIMIT 10 OFFSET 0

+-----+---------+------------------+
| id  | user_id | receiver_user_id |
+-----+---------+------------------+
| 115 |       2 |                1 |
| 113 |       1 |                3 |
| 111 |       1 |                2 |
| 116 |       1 |                4 |
+-----+---------+------------------+

结果(预期)

+-----+---------------------+
| id  | MAX(updated_at)     |
+-----+---------------------+
| 114 | 2015-06-18 08:37:51 |
| 115 | 2015-06-18 09:28:49 |
| 117 | 2015-06-18 10:20:29 |
+-----+---------------------+

+-----+---------+------------------+
| id  | user_id | receiver_user_id |
+-----+---------+------------------+
| 114 |       1 |                3 |
| 115 |       2 |                1 |
| 117 |       1 |                4 |
+-----+---------+------------------+

1 个答案:

答案 0 :(得分:0)

如果你的结果集中没有出现这么多错误,你昨天可能会得到答案; - )

DROP TABLE IF EXISTS jobs;

CREATE TABLE jobs
(id INT NOT NULL PRIMARY KEY
,user_id INT NOT NULL
,receiver_user_id INT NOT NULL
,updated_at DATETIME NOT NULL
);

INSERT INTO jobs VALUES
(111,1,2,'2015-06-18 08:23:55'),
(112,1,2,'2015-06-18 08:28:40'),
(113,1,3,'2015-06-18 08:37:32'),
(114,1,3,'2015-06-18 08:37:51'),
(115,2,1,'2015-06-18 09:28:49'),
(116,1,4,'2015-06-18 09:29:58'),
(117,1,4,'2015-06-18 10:20:29');

SELECT a.*
  FROM jobs a
  JOIN 
     ( SELECT MAX(id) max_id 
         FROM
            (
              SELECT id, user_id FROM jobs WHERE receiver_user_id = 1
              UNION
              SELECT id, receiver_user_id FROM jobs WHERE user_id = 1
            ) n
        GROUP 
           BY user_id
     ) b
   ON b.max_id = a.id;

+-----+---------+------------------+---------------------+
| id  | user_id | receiver_user_id | updated_at          |
+-----+---------+------------------+---------------------+
| 114 |       1 |                3 | 2015-06-18 08:37:51 |
| 115 |       2 |                1 | 2015-06-18 09:28:49 |
| 117 |       1 |                4 | 2015-06-18 10:20:29 |
+-----+---------+------------------+---------------------+