查找每个组件的最新记录MySQL

时间:2015-06-23 05:55:06

标签: mysql sql group-by sql-order-by

我有一个定期报告状态的组件列表。

我想编写一个查询来查找按组件分组的最新状态列表。

通常我会使用此问题的接受答案所描述的解决方案:MySQL order by before group by

但是每秒可以报告多个状态,因此无法保证我将检索最新的状态。因此,我想找到具有最新时间戳的状态,如果是重复时间戳,则查找具有最高时间戳的状态。

理想情况下,我希望得到如下查询:

SELECT *
FROM component_status 
ORDER BY component_status.timestamp DESC, component_status.component_status_id DESC
GROUP BY component_status.component_id;

但是,您无法在ORDER BY之后执行GROUP BY。

是否有人遇到类似问题并找到解决方案?

3 个答案:

答案 0 :(得分:1)

您可以使用变量来模拟

 ROW_NUMBER() OVER (PARTITION BY component_id 
                    ORDER BY `timestamp` DESC, component_status_id DESC)

窗口功能:

SELECT component_id, component_status_id, `timestamp`
FROM (
SELECT component_id, component_status_id, `timestamp`, 
       @row_number:= 
          IF (@cid <> component_id,
             IF (@cid := component_id, 1, 1),
             IF (@cid := component_id, @row_number + 1, @row_number + 1)) AS rn   
FROM component_status
CROSS JOIN (SELECT @row_number:= 0, @cid := -1) vars
ORDER BY `timestamp` DESC, component_status_id DESC ) t
WHERE rn = 1
外部查询中的

rn=1选择每component_id的最新记录。如果有两个或多个记录具有相同的timestamp,则将选择具有最大component_status_id的记录。

Demo here

答案 1 :(得分:0)

它不能提供正确的结果,因为order by在group by之后工作,为此您可以先通过子查询中的结果获得订单,然后您可以对它们进行分组。

例如 -

select field1, field2 from (SELECT field1,field2,...,component_status.component_id  
FROM component_status 
ORDER BY component_status.timestamp DESC, component_status.component_status_id DESC) a 
GROUP BY a.component_id;

答案 2 :(得分:0)

我最终使用以下查询来解决我的问题:

SELECT 
    component_status.*
FROM
    component_status
JOIN
    (SELECT 
        MAX(component_status_id) AS component_status_id
    FROM
        component_status
    JOIN 
        (SELECT 
            MAX(timestamp) AS timestamp, component_id
        FROM
            component_status
        WHERE
            timestamp <= NOW()
        GROUP BY component_id) AS most_recent_status 
    USING (component_id)
    WHERE component_status.timestamp = most_recent_status.timestamp
    GROUP BY component_id) AS most_recent_status 
USING (component_status_id)

使用component_id和timestamp上的复合索引,查询是即时的。