如何按Head父级分组排列SQL表行,使子行紧跟对应父行?
实现父子测试行的层级排序方法
我明白你的需求了——你希望每个父测试行(HeadID为null的行)后面立刻跟着它对应的所有子测试行,而不是先把所有父行都列完再展示子行。
先梳理下你的数据和当前问题:
原始表数据
+----+--------+----------+--------+ | ID | TestNo | TestName | HeadID | +----+--------+----------+--------+ | 1 | 21 | Comp-1 | null | | 2 | 22 | C1 | 21 | | 3 | 23 | C2 | 21 | | 4 | 24 | C3 | 21 | | 5 | 47 | Comp-2 | null | | 6 | 25 | C4 | 47 | | 7 | 26 | C1+ | 21 | +----+--------+----------+--------+
当前ORDER BY HeadID的输出
+----+--------+----------+--------+ | ID | TestNo | TestName | HeadID | +----+--------+----------+--------+ | 1 | 21 | Comp-1 | null | | 5 | 47 | Comp-2 | null | | 2 | 22 | C1 | 21 | | 3 | 23 | C2 | 21 | | 4 | 24 | C3 | 21 | | 7 | 26 | C1+ | 21 | | 6 | 25 | C4 | 47 | +----+--------+----------+--------+
期望的输出
+----+--------+----------+--------+ | ID | TestNo | TestName | HeadID | +----+--------+----------+--------+ | 1 | 21 | Comp-1 | null | | 2 | 22 | C1 | 21 | | 3 | 23 | C2 | 21 | | 4 | 24 | C3 | 21 | | 7 | 26 | C1+ | 21 | | 5 | 47 | Comp-2 | null | | 6 | 25 | C4 | 47 | +----+--------+----------+--------+
解决方案
你需要调整排序逻辑,让父行和它的子行归为同一排序组,同时确保父行在组内先显示。可以用下面的SQL语句:
SELECT * FROM ranges ORDER BY -- 把父行和对应的子行分到同一组:父行用自己的TestNo,子行用HeadID(即父行的TestNo) COALESCE(HeadID, TestNo), -- 让父行(HeadID为null)排在子行前面 CASE WHEN HeadID IS NULL THEN 0 ELSE 1 END, -- 子行内部可以按TestNo排序,也可以换成ID按创建顺序排序 TestNo;
逻辑解释
COALESCE(HeadID, TestNo):这个函数会返回第一个非null的值。对于父行,HeadID是null,所以取TestNo;对于子行,取HeadID(也就是对应父行的TestNo)。这样父行和它的所有子行就会被分到同一个排序组里。CASE WHEN HeadID IS NULL THEN 0 ELSE 1 END:给父行标记为0,子行标记为1,确保父行在组内排在最前面。TestNo:最后对子行内部按TestNo排序,如果你想按ID顺序排列子行,把这里换成ID即可。
执行这个语句后,就能得到你期望的层级排序效果了。
内容的提问来源于stack exchange,提问作者Ahsan Ali
相关产品推荐
相关产品推荐

