使用“Updated From”列获取最新更新数据的SQL查询

时间:2015-03-20 05:37:33

标签: mysql common-table-expression

我正在处理包含具有此类架构的表的旧数据库。

+----+------+--------------+
| id | name | updated_from |
+----+------+--------------+
| 1  | A    | NULL         |
| 2  | B    | NULL         |
| 3  | AA   | 1            |
| 4  | BB   | 2            |
| 5  | AAA  | 3            |
+----+------+--------------+

我尝试做的是获取特定id的最新更新,例如,如果我想知道来自A的{​​{1}}或id=1的最新更新当然是AA。遗憾的是,架构没有AAA列。

为了方便起见,这是我搜索timestamp时的预期结果。

+----+------+--------------+
| id | name | updated_from |
+----+------+--------------+
| 1  | A    | NULL         |
| 3  | AA   | 1            |
| 5  | AAA  | 3            |
+----+------+--------------+

我为任何不明确的解释道歉,并提前致谢。

编辑: 为了更清楚,我希望这可以提供帮助:

id=3

每次更新任何行,前一行复制id并将其放入1:A:NULL -> 3:AA:1 -> 5:AAA:3列进入新行,这使它们像链接一样。

鉴于这个例子,如果我搜索任意ID,我将获得前一个也是下一个链ID。

在阅读@ hofan41评论后,我来回答Generating Depth based tree from Hierarchical Data in MySQL (no CTEs)

导致我修改版的@ f00答案。 模式和示例数据与我提供的第一个表完全相同。

drop procedure if exists `table1_hier`;

delimiter #

create procedure table1_hier (
    in updated_from_id smallint unsigned
)

begin

declare v_done tinyint unsigned default 0;
declare v_depth smallint unsigned default 0;

drop temporary table if exists hier;
create temporary table hier (
    updated_from smallint unsigned,
    name_id smallint unsigned,
    depth smallint unsigned default 0
) engine = memory;

insert into hier
    select updated_from, id, v_depth
    from table1
    where id = updated_from_id;

create temporary table tmp engine = memory select * from hier;

while not v_done do
    if exists(select 1
              from table1 p inner join hier on p.updated_from = hier.name_id
              and hier.depth = v_depth) then

        insert into hier
            select p.updated_from, p.id, v_depth + 1 from table1 p
            inner join tmp on p.updated_from = tmp.name_id and tmp.depth = v_depth;

        set v_depth = v_depth + 1;

        truncate table tmp;
        insert into tmp select * from hier where depth = v_depth;
    else
        set v_done = 1;
    end if;
end while;

select
    p.id,
    p.name,
    b.id as updated_from,
    b.name as name_from,
    hier.depth
from
    hier
    inner join table1 p on hier.name_id = p.id
    left outer join table1 b on hier.updated_from = b.id
order by
    hier.depth, hier.name_id;

drop temporary table if exists hier;
drop temporary table if exists tmp;

end #

但是如果我用updated_from搜索,我只得到下一个链ID而不是前一个。

+----+------+--------------+-----------+-------+
| id | name | updated_from | name_from | depth |
+----+------+--------------+-----------+-------+
| 3  | AA   | 1            | A         | 0     |
| 5  | AAA  | 3            | AA        | 1     |
+----+------+--------------+-----------+-------+

0 个答案:

没有答案