优先考虑MySQL中的左连接行

时间:2012-05-22 04:13:54

标签: mysql join

我正在处理MySQL(5.5)中一些有些棘手的数据。我有一个表用于跟踪状态(新的,活动的,非活动的等)和“位置”更改,其中位置的格式为x.0.y,x和y为正整数。 / p>

我正在尝试将位置更改移动到单独的表中,但为了这样做,我需要从表中的其他记录中恢复完整的旧位置。完整的旧位置不会存储在位置更改记录中,如下所示:

id      status      new_loc     timestamp
--      ------      -------     ---------
5       1 -> 1      1.0.2       2012-05-21 00:00:00
5       new         1.0.1       2012-05-21 00:00:03
5       1 -> 2      2.0.1       2012-05-22 00:00:00
5       2 -> 3      3.0.1       2012-05-23 00:00:00

因此,当位置发生变化时,所记录的全部是全新位置和旧位置的第一部分(状态消息的左侧)。但是,我可以查看以前的记录,找到完整的旧位置。

我的主要问题是第二排。 “新”状态表示id为5的对象刚刚添加到数据库中。它应该始终是表中任何id的第一个状态。但是,在初始更改记录之后大约三秒内插入“新”记录的情况很多。在这种情况下,它添加了位置1.0.1,然后更改为1.0.2,然后更改为2.0.1,然后更改为3.0.1。 (编辑:真实的例子不是这么简单或直截了当,但总有一个人类可以很容易辨别出的“路径”。)

我在尝试编写一个同时考虑第1行和第3行的查询时遇到了问题。我不能只找到最新的记录,因为它们可能不正常。我不能只使用与我的状态匹配的new_loc获取记录,因为可能有多个匹配。

以下是我认为的作用:

  1. 查找最近的先前位置更改(如果存在),并使用其new_loc。
  2. 如果不存在先前的更改,请找到该ID的“新”状态记录并使用其new_loc。
  3. 我目前有一个LEFT JOIN与这两个条件相匹配,但我不知道如何说“只有条件2才加入条件2”或“首选条件1加入行。”

    我无法弄清楚如何做到这一点。任何帮助表示赞赏。

    编辑:我应该明确id是一个对象id,显然不仅仅是这个表的索引。主键是(id,status)。

1 个答案:

答案 0 :(得分:0)

让我确认一下,我明白你要做什么。在伪代码中,这会做你想要的吗?

given
   table A (as in your answer)
   table B (objectid, old, new)
for any `id`
   get all rows
   order rows by `status` column such that 'new' is the first value, and then numerically
   take the location in the first `status` column c and insert it into table B with values id, 'new', (c).location
   for all remaining `status` fields selected: 
       for any field n, insert into table B with values id, (n-1).location, (n).location

使用存储过程应该是可能的......但是编写代码可能会很痛苦。