0

我有个问题对应SQL/Mysql的join操作。

我的数据库表结构有以下字段

时间戳

纬度双

隆双

所以实际数据是这样的

| 2013-07-20 16:32:22 | 49.3 | 8.3 |

| 2013-07-20 16:17:09 | 49.2 | 8.2 |

| 2013-07-20 15:58:19 | 49.1 | 8.1 |

我现在想将这个表与其自身连接起来,以便将一个数据集与具有下一个较低时间戳的数据集连接起来。所以这两者之间的差异是最小的。

所以最后我的结果是

| 2013-07-20 16:32:22 | 49.3 | 8.3 | 2013-07-20 16:17:09 | 49.2 | 8.2 |

| 2013-07-20 16:17:09 | 49.2 | 8.2 | 2013-07-20 15:58:19 | 49.1 | 8.1 |

为了到达那里,我尝试了以下 SQL 语句

SELECT * FROM positionp1 , positionp2 WHERE p1.time > p2.time GROUP BY p1.time;

但结果并不完全符合我的预期,第二个(分组依据)部分没有被这个解决方案“正确”排序。它看起来像这样:

| 2013-07-20 16:32:22 | 49.3 | 8.3 | 2013-07-20 15:58:19 | 49.1 | 8.1 |

| 2013-07-20 16:17:09 | 49.2 | 8.2 | 2013-07-20 15:58:19 | 49.1 | 8.1 |

谁能告诉我我的预期结果是否可以通过使用 SQL 实现?

4

2 回答 2

1

这确实是可能的。不幸的是,MySQL 缺少使这变得容易的功能。

我会对行进行排名,然后按排名加入:

select 
  p1.time as time1,
  p1.lat as lat1,
  p1.lon as lon1,
  p1.rank as rank1,
  p2.time as time2,
  p2.lat as lat2,
  p2.lon as lon2,
  p2.rank as rank2
from (
  select position.*,
    @curRank1 := @curRank1 + 1 AS rank 
  from position , (SELECT @curRank1 := 0) r 
  order by time desc) p1
join (
  select position.*,
    @curRank2 := @curRank2 + 1 AS rank 
  from position , (SELECT @curRank2 := 0) r 
  order by time desc) p2
on p1.rank = p2.rank -1

这是显示它的小提琴:http ://sqlfiddle.com/#!2/d777f/8

于 2013-07-20T16:51:27.000 回答
1

在我看来,这也是一种更具“可读性”的可能性:

select 
  p1.time as time1,
   (select min(p2.time) as time2
    from position p2
    where p2.time > p1.time)
from position p1

但请注意,这种可读性具有二次复杂性,因为子查询将针对p1. 如果你的表足够大,你应该使用 jtseng 的代码。

PS:用于查看查询计划的Sqlfiddle:http ://sqlfiddle.com/#!2/d777f/10

PPS:包含其他字段后,可能如下所示:

select 
  p1.time as time1,
  p1.lat as lat1,
  p1.lon as lon1,
  p2.time as time2,
  p2.lat as lat2,
  p2.lon as lon2
from
  position p1,
  position p2
where
  p2.time = (select min(p.time)
   from position p
   where p.time > p1.time)

仍然具有更好的可读性,但也为 p1 中的每一行发出依赖子查询。

于 2013-07-20T17:10:34.993 回答