我正在使用SQL Server 2008 R2,我有一个复杂的排序问题,但是我找不到解决方案。
为了更好地解释,我在下面发布了一个样例查询。在这个查询中,我们试图显示位置层次结构,但是虽然父/子关系被正确排序,但它们在它们的关系内部不是按字母顺序排序的。正如您所看到的,"东海岸"和"西海岸"都是顶级位置,因为它们的父位置(f_locationparent)等于(0)。然而,我希望"东海岸"在"西海岸"之前显示。显然,我不能简单地按
以下是当前的查询:
为了更好地解释,我在下面发布了一个样例查询。在这个查询中,我们试图显示位置层次结构,但是虽然父/子关系被正确排序,但它们在它们的关系内部不是按字母顺序排序的。正如您所看到的,"东海岸"和"西海岸"都是顶级位置,因为它们的父位置(f_locationparent)等于(0)。然而,我希望"东海岸"在"西海岸"之前显示。显然,我不能简单地按
f_locationname
,然后按f_lineage
排序,因为这样关系就不能按正确的顺序显示。重要提示:顶级位置的父位置始终为(0),因为它们没有父项。f_locationid f_locationparent f_locationname f_level f_lineage
-------------------------------------------------------------------------
4 0 West Coast 0 0_4
5 4 Los Angeles 1 0_4_5
6 5 Del Rey 2 0_4_5_6
7 5 Reseda 2 0_4_5_7
8 5 Crenshaw 2 0_4_5_8
9 0 East Coast 0 0_9
10 9 New York City 1 0_9_10
1 10 Queens 2 0_9_10_1
2 10 Bronx 2 0_9_10_2
3 10 Manhattan 2 0_9_10_3
以下是当前的查询:
;WITH cte_locationlineage AS
(
SELECT a.f_locationid, a.f_locationparent, a.f_locationname, 0 AS f_level,
CONVERT(varchar(30), '0_' + convert(varchar(10), f_locationid)) f_lineage
FROM tb__templocations a
WHERE f_locationparent = '0'
UNION ALL
SELECT a.f_locationid,
a.f_locationparent,
a.f_locationname,
c.f_level + 1,
CONVERT(varchar(30), f_lineage + '_'
+ convert(varchar(10), a.f_locationid))
FROM cte_locationlineage c
JOIN tb__templocations a
ON a.f_locationparent = c.f_locationID
)
SELECT *
FROM cte_locationlineage c
ORDER BY f_lineage
正如您所看到的,它是基于血统排序的,这是位置ID(f_locationID)的组合。不幸的是,正如您所看到的,位置ID并不总是按字母顺序排列。
这里是一个SQL Fiddle,您可以看到它是如何工作的。
最终,使用相同的数据,这是我想要看到的结果查询,在父级下的关系中,项目按字母顺序排序。因此,对于“东海岸”祖父和“纽约市”父母,列在其下面的子项是按字母顺序排列的。
f_locationid f_locationparent f_locationname f_level f_lineage
-------------------------------------------------------------------------
9 0 East Coast 0 0_9
10 9 New York City 1 0_9_10
2 10 Bronx 2 0_9_10_2
3 10 Manhattan 2 0_9_10_3
1 10 Queens 2 0_9_10_1
4 0 West Coast 0 0_4
5 4 Los Angeles 1 0_4_5
8 5 Crenshaw 2 0_4_5_8
6 5 Del Rey 2 0_4_5_6
7 5 Reseda 2 0_4_5_7