如何对同一 table 中的两个 GUID 字段按时间顺序排序?

How do I sort into chronological order of two GUID fields from same table?

问题

我有一个带有两个 GUID 字段的 table,其中一个指示哪个 GUID(SuperiorGUID)优于该行(ObjectGUID)。此 table 存在于 MySQL 5.7 数据库中。我需要按这两个字段的菊花链对 table 中的行进行排序。

如何在最新版本为 SuperiorGUID = 'ffffffff-ffff-ffff-ffff-ffffffffffff' 的情况下按顺序排列 ObjectGUID?

Table VersionTracking vt

ObjectGUID SuperiorGUID
15c9cc74-7653-4000-a3a7-8ab7efe5f5f4 6797d1f2-b81c-4db9-8a8b-ce3e9afc96f7
2bb02d4b-a444-11eb-8b72-000c29e16cdc d72fe08a-2034-4615-96b9-a4e3e2d496a1
6797d1f2-b81c-4db9-8a8b-ce3e9afc96f7 ab921294-6d3a-4cb3-8adb-3f0f76fa8635
a637d8be-8840-4053-9082-9e86b141ddca ffffffff-ffff-ffff-ffff-ffffffffffff
ab921294-6d3a-4cb3-8adb-3f0f76fa8635 a637d8be-8840-4053-9082-9e86b141ddca
d72fe08a-2034-4615-96b9-a4e3e2d496a1 15c9cc74-7653-4000-a3a7-8ab7efe5f5f4

期望输出

ObjectGUID SuperiorGUID
a637d8be-8840-4053-9082-9e86b141ddca ffffffff-ffff-ffff-ffff-ffffffffffff
ab921294-6d3a-4cb3-8adb-3f0f76fa8635 a637d8be-8840-4053-9082-9e86b141ddca
6797d1f2-b81c-4db9-8a8b-ce3e9afc96f7 ab921294-6d3a-4cb3-8adb-3f0f76fa8635
15c9cc74-7653-4000-a3a7-8ab7efe5f5f4 6797d1f2-b81c-4db9-8a8b-ce3e9afc96f7
d72fe08a-2034-4615-96b9-a4e3e2d496a1 15c9cc74-7653-4000-a3a7-8ab7efe5f5f4
2bb02d4b-a444-11eb-8b72-000c29e16cdc d72fe08a-2034-4615-96b9-a4e3e2d496a1

演示最大链长度为 3,我会这样做:

select
    elt(d, vt1.ObjectGUID, vt2.ObjectGUID, vt3.ObjectGUID) ObjectGUID,
    elt(d, vt1.SuperiorGUID, vt2.SuperiorGUID, vt3.SuperiorGUID) SuperiorGUID
from (
    select 1 d union all select 2 union all select 3
) depths
cross join vt vt1
left join vt vt2 on d>=2 and vt2.SuperiorGUID=vt1.ObjectGUID
left join vt vt3 on d>=3 and vt3.SuperiorGUID=vt2.ObjectGUID
where vt1.SuperiorGUID='ffffffff-ffff-ffff-ffff-ffffffffffff'
order by d

这对我来说似乎比基于子查询的解决方案更直接,但受到 61 个连接表的限制。

递归查询解决方案,MySQL8.0可用:

WITH RECURSIVE cte AS (
  SELECT ObjectGUID, SuperiorGuid, 1 AS level
  FROM MyTable
  WHERE SuperiorGuid = 'ffffffff-ffff-ffff-ffff-ffffffffffff'
  UNION ALL
  SELECT m.ObjectGuid, m.SuperiorGuid, cte.level+1
  FROM MyTable AS m JOIN cte ON m.SuperiorGuid = cte.ObjectGUID 
)
SELECT ObjectGUID, SuperiorGUID FROM cte ORDER BY level;