我有一个表格,其中每一行都有一个From和一个To:
From|To
A | B
C | D
B | C
D | E
我需要按顺序对它们进行排序,其中第一行中的“To”是以下的“From”,依此类推。
结果应按如下顺序排列:
From|To
A| B
B| C
C| D
D| E
主要问题是在上一条记录中找到To后面的To。
答案 0 :(得分:1)
不确定我的问题是否正确。你为什么不排序?
;with cte as
(
select 'B' as "From", 'C' as "To"
union
select 'A', 'B'
union
select 'C', 'D'
)
select "From", "To"
from cte
order by "From";
(您的查询中不需要cte / union内容,只是为了样本数据。)
如果您只想列出包含后继者的条目:
;with cte as
(
select 'B' as "From", 'C' as "To"
union
select 'A', 'B'
union
select 'C', 'D'
union
select 'F', 'G'
)
select "From", "To"
from cte
where exists(select *
from cte cte2
where cte2."From" = cte."To")
or exists(select *
from cte cte3
where cte3."To" = cte."From")
order by "From";
顺便说一句:尝试使用除“From”和“To”之外的其他列名,因为它们是必须与“”(ANSI)或[](T SQL)一起使用的保留语句。
答案 1 :(得分:0)
declare @v table (ffrom varchar(10), fto varchar(10)); insert into @v values ('e', 'f'), ('a', 'b'), ('g', 'h'), ('c', 'd'); select * from @v order by ffrom;
GO
ffrom | fto :---- | :-- a | b c | d e | f g | h
dbfiddle here
答案 2 :(得分:0)
您可以使用递归CTE:
with cte as (
select from, to, 1 as lev
from t
where not exists (select 1 from t t2 where t2.to = t.from)
union all
select t.from, t.to, cte.lev + 1
from cte join
t
on cte.to = t.from
)
select to, from
from cte
order by lev, to;
请注意,这受最大递归深度的影响,但它可以在四行上正常工作。