SQL查询:为每个不同的字段值选择最近的条目?

Nul*_*ion 0 sql

我有这张桌子位置:

CREATE TABLE `position` (
  `idposition` bigint(20) NOT NULL AUTO_INCREMENT,
  `latitude` varchar(45) DEFAULT NULL,
  `longitude` varchar(45) DEFAULT NULL,
  `timestamp` datetime DEFAULT NULL,
  `fk_email` varchar(100) DEFAULT NULL,
Run Code Online (Sandbox Code Playgroud)

这个人口:

idposition  latitude    longitude   timestamp              fk_email
        1   39.49333    -0.33667    2010-12-10 17:15:39     david@test.es
         4  39.47333    -0.36167    2010-12-11 09:58:47     ronald@test.es
         5  39.50333    -0.34267    2010-12-10 21:11:10     david@test.es
        10  39.44333    -0.41667    2010-12-12 18:17:26     fanny@test.es
        11  39.45199    -0.31967    2010-12-12 21:01:18     victor@test.es
        12  39.52133    -0.36167    2010-12-12 17:43:11     carlos@test.es
        13  39.43199    -0.31967    2010-12-14 15:45:25     victor@test.es
        14  39.41199    -0.34567    2010-12-14 20:46:09     victor@test.es
        15  39.43433    -0.41667    2010-12-14 17:29:39     maria@test.es
        16  39.44133    -0.42667    2010-12-12 19:17:33     maria@test.es
        17  39.50333    -0.35667    2010-12-13 16:36:22     angel@test.es
        196     39.46454    -0.38978    0000-00-00 00:00:00     fanny@test.es
        271     33.63883    -0.45024    2010-12-17 11:36:45     fanny@test.es
        273     39.46680    -0.39452    2010-12-20 00:00:00     fanny@test.es
        441     39.44133    -0.41467    2010-12-15 17:45:13     carlos@test.es
        5326    39.47316    -0.38351    2011-01-18 18:09:56     pablo@upv.es
Run Code Online (Sandbox Code Playgroud)

好吧,我想做SQL查询,它返回给我每个FK_EMAIL的最后(最新)位置,我的意思是,对于每个fk_email,timestamp每个电子邮件的最后一个(最新),只有一个位置(最后一个)的位置.

有可能做到吗?有人可以帮我查询吗?对我来说太难了

Con*_*rix 5

SELECT  
      p.idposition, 
      p.atitude, 
      p.longitude, 
      p.timestamp, 
      p.fk_email

FROM  
      position p 
      INNER JOIN (select 
              fk_email,
              max(timestamp) timestamp
                 FROM    POSITION 
                 GROUP BY  fk_email) lastPos 
      ON p.fk_email = lastPos.fk_email and p.timeStamp = lastpos.timestamp
Run Code Online (Sandbox Code Playgroud)

这个问题的一个潜在问题是,如果为同一个fk_email记录了相同的时间戳,您将获得两个结果.如果这两个列的组合存在唯一约束,则不必担心这一点.

更新 来自评论

但是还有一个问题,每个电子邮件返回两行的唯一可能性是将同一封电子邮件的两行中的seame时间戳设置为?我怎么能逃避这一点

正如我之前所说,在两个字段上添加一个唯一约束,所以它不会发生是最简单的.但是我们假设您不能这样做,并且还假设时间戳是相同的.你需要选择任意一行作为"正确的".

假设IdPosition是唯一的,你可以这样做

SELECT 
     p.idposition, 
      p.atitude, 
      p.longitude, 
      p.timestamp, 
      p.fk_email
  FROM 
   position p
    INNER JOIN (SELECT  
                    max(p.idposition) idposition
              FROM  
                    position p 
                    INNER JOIN (select 
                            fk_email,
                            max(timestamp) timestamp
                               FROM    POSITION 
                               GROUP BY  fk_email) lastPos 
                    ON p.fk_email = lastPos.fk_email and p.timeStamp = lastpos.timestamp
              GROUP BY 
                     fk_email) lastpos
              on p.idposition = lastpos.idposition
Run Code Online (Sandbox Code Playgroud)