我正在尝试重建具有树结构的数据。
示例 - 国家/城市:
1) USA
1.1) New York
1.2) Chicago
2) France
2.1) Paris
2.2) Lyon
3) China
在我的数据库中,它看起来像这样:
| Element | Level | Row |
|:--------:|:-----:|:---:|
| USA | 1 | 1 |
| New York | 2 | 2 |
| Chicago | 2 | 3 |
| France | 1 | 4 |
| Paris | 2 | 5 |
| Lyon | 2 | 6 |
| China | 1 | 7 |
根据我的条目的顺序(行),我可以重建树结构。对于每一行,我查找最近的具有Level-1的前一行。
max(pre.Row)/ pre.Row< cur.Row / pre.Level = cur.Level-1
以下代码正常运行并返回正确的结果。我的问题是该表是700万行大,因此需要花费很多时间。这就像比较700万次700万行...
SELECT cur.`Row`, (
SELECT max(pre.`Row`)
FROM `abc`.`def` AS pre
WHERE pre.`Row` < cur.`Row`
AND pre.`Level`=cur.`Level`-1
) AS prev_row
FROM `abc`.`def` AS cur
;
有更快的方法来实现这个吗?
可能有循环或用户变量?我可以想象你实际上从当前行开始,然后测试前一行是否满足条件,否则查找下一行,依此类推。这将把操作减少到700万〜5。我从来没有使用循环,所以我不知道如果在SQL中这是可能的。有什么想法吗?
答案 0 :(得分:0)
这里我尝试了3个等级你可以添加等级,如果你有更多,不知道为什么它会返回看起来像编码值的奇怪值但CAST()AS unSIGNED会让你prev_row就像你的查询。
SELECT Row,
CAST(ELT(level-1,@level_1,@level_2,@level_3) as UNSIGNED) as prev_row,
@level_1 := IF(`level` = 1, row, @level_1),
@level_2 := IF(`level` = 2, row, @level_2),
@level_3 := IF(`level` = 3, row, @level_3)
FROM `def`
ORDER BY Row ASC