2013-04-26 34 views
3

我想从以下行动表检索表PostgreSQL的问题:Rails和使用具有

列:ID,名称,状态,对于这个问题PRODUCT_ID,USER_ID和其他一些非相关列。

每次用户需要产品时,我都会创建如下记录: Name = Want,Status = True,Product_ID =想要的产品的ID,User_ID是用户的ID。

然后每次用户不愿意产品时,我都会创建如下记录: Name = Want,Status = False,Product_ID =产品不需要的ID,User_ID是用户的ID。

我这样做是因为我的表中有其他动作的名字。

现在我想要检索所有想要的产品,因此我应该检索所有最后想要的操作,这些操作按照降序created_at排序的特定用户的product_id分组,然后只检索status = true的操作。

所以让所有的最后希望为用户我没有通过的product_id分组行动:

Action.select("DISTINCT ON (product_id) product_id,created_at, status, * ").where{(user_id == id) & (name == 'want')}.group("product_id, id, status").order(' product_id,created_at DESC') 

这检索每个产品和用户最后一次行动,但同时检索真假状态 唯一的问题是我不知道如何过滤这个表,只有在这个行为是真的时才会得到这个行为。

我试图做这样的:

Action.select("DISTINCT ON (product_id) product_id,created_at, status, * ").where{(user_id == id) & (name == 'want')}.group("product_id, id, status").having("status = 'true'").order(' product_id,created_at DESC') 

但是,这会给我这里想= true的最后一个动作。如果最后一个动作是status = false,那么当状态=真时,它将检索到之前的动作。

我真的希望这是非常明显的,

感谢您的帮助

这里是我想要的东西的想法,但我不知道如何实现与轨道: http://sqlfiddle.com/#!9/e4117/3

回答

1

您可以尝试添加一个子查询条件并删除该组:

Action. 
    where(user_id: id, name: "want", status: "true"). 
    where(["id IN (SELECT max(id) FROM actions WHERE user_id = ? 
       AND name = 'want' GROUP BY product_id)", id]). 
    order("product_id") 

您需要r依赖id列的顺序作为这个工作的最后一个动作。如果你不能做到这一点,你可以在子查询中使用DISTINCT ON:

Action. 
    where(user_id: id, name: "want", status: "true"). 
    where(["id IN (SELECT DISTINCT ON (product_id) id FROM actions 
       WHERE user_id = ? AND name = 'want' 
       ORDER BY product_id, created_at DESC)", id]). 
    order("product_id") 
+0

如果我这样做,会给我所有的状态真的,但如果我有一个:最后一个项目是假的地位和项目前最后一个是真实的,它会在最后一个之前给我这个项目。如果它不是最后一项,我希望它不返回任何内容。谢谢, – 2013-04-26 13:00:25

+0

编辑我的回答 – lassej 2013-04-26 13:27:31

+0

感谢只有一个问题,虽然:ORDER BY product_id,created_at DESC)“,user_id])。 order(”product_id“)should user_id be id?thanks, – 2013-04-26 14:00:09