MySQL - 选择ID下的行,按列值选择具有最新时间戳的行

时间:2016-11-11 14:36:20

标签: mysql sql database

表:

----------------------------------------------------
ID | field_name | field_value | timestamp
----------------------------------------------------
2  | postcode   | LS1         | 2016-11-09 16:45:15
2  | age        | 34          | 2016-11-09 16:45:22
2  | job        | Scientist   | 2016-11-09 16:45:27
2  | age        | 38          | 2016-11-09 16:46:40
7  | postcode   | LS5         | 2016-11-09 16:47:05
7  | age        | 24          | 2016-11-09 16:47:44    

我想知道是否有人可以根据上述数据给我一些指示,我想通过ID 2查询,为每个唯一的field_name返回一行(如果同一个id下存在多行,则相同field_name然后只返回带有最新时间戳的行。

我已经设法通过对field_name进行分组来实现这一点,field_name将返回唯一行的列表,但不一定是最新的行。

SELECT * FROM fragment WHERE (id = :id) GROUP BY field_name

我真的很感激有关我应该在这里做什么的指示,以及我如何在这个查询中按照MAX(时间戳)的方式拟合某些内容,

非常感谢!

2 个答案:

答案 0 :(得分:1)

考虑您首先需要每个ID的一组数据,FieldName和最大时间戳。 (生成该集合)作为内联视图(下面的B)。然后,将此集合(B)连接回基础集,允许内部联接消除不需要的行。

SELECT A.ID, A.field_name, A.field_value, A.timestamp
FROM Table A
INNER JOIN (SELECT ID, field_name, MAX(timestamp) TS 
            FROM table 
            GROUP BY ID, field_name) B
 on A.ID = B.ID
and A.field_name = B.field_name
and A.timestamp = B.TS

在MySQL之外,这可以使用窗口/分析功能来完成,因为您可以为每个记录分配行号并消除那些>有点像....

SELECT B.* 
FROM (SELECT A.ID
           , A.field_name
           , A.field_Vale
           , A.timestamp
           , Rownumber() over (Order by A.timestamp Desc) RN
      FROM Table A ) B
WHERE B.RN = 1

或使用带限制或顶部的交叉申请。

答案 1 :(得分:1)

最简单的方法:

  SELECT *
  FROM fragment fra1
  WHERE (id = :id)
    and timestamp = (select max(timestamp)
                     from fragment fra2
                     where fra2.id = fra1.id
                       and fra2.field_name = fra1.field_name)
  GROUP BY field_name