2013-12-17 57 views
0

我有一个元数据表看起来像这样的:查找最高值列各组

+----------------------------+ 
|  metadata   | 
+----+----------+------------+ 
| id | group_id | message_id | 
+----+----------+------------+ 
| 1 | 1  |  5  | 
+----+----------+------------+ 
| 2 | 2  |  6  | 
+----+----------+------------+ 
| 3 | 1  |  8  | 
+----+----------+------------+ 
| 4 | 2  |  10  | 
+----+----------+------------+ 

对于每个group_id,我想选择具有最高id 行所以我想回来:

+----------------------------+ 
|   results   | 
+----+----------+------------+ 
| id | group_id | message_id | 
+----+----------+------------+ 
| 3 | 1  |  8  | 
+----+----------+------------+ 
| 4 | 2  |  10  | 
+----+----------+------------+ 

我在想这将是这样的事情,但以下只返回行4。从我想选择MAX(metadata.id)

SELECT 
    MAX(metadata.id) 
FROM 
    metadata 
GROUP BY 
    metadata.message_id 

假设Metadatum是一个ActiveRecord模型组,每组,并groupbelongs_to关系,你将如何构建这个查询与AR?

回答

0

产生的预期结果查询(假设id是唯一的):

SELECT t1.* FROM t AS t1 
JOIN (
    SELECT max(id) AS id FROM t 
    GROUP BY group_id 
) t2 ON t1.id = t2.id 

输出:

| ID | GROUP_ID | MESSAGE_ID | 
|----|----------|------------| 
| 3 |  1 |   8 | 
| 4 |  2 |   10 | 

小提琴here

但是,我不完全明白你的意思是由AR查询。要做到这一点

+0

通过AR我的意思是活动记录查询(即使用活动记录方法构建的查询)。 – dyln

1

一种方法是使用row_number()

SELECT m.id 
FROM (select m.*, 
      row_number() over (partition by m.message_id order by m.id desc) as seqnum 
     from metadata m 
    ) m 
WHERE seqnum = 1; 

在Postgres里,你也可以用distinct on做到这一点:

select distinct on (m.message_id), m.id 
from metadata m 
order by m.message_id, m.id; 
0

正如编程的乐趣,这里是另一种解决方案

SELECT t1.* 
FROM metadata AS t1 
WHERE t1.id = (
    SELECT t2.id 
    FROM metadata AS t2 
    WHERE t2.group_id = t1.group_id 
    ORDER BY t2.id DESC 
    LIMIT 1 
)