如何在SQL中创建顺序范围?

时间:2017-03-24 19:26:51

标签: sql sql-server sql-server-2008

我有一个表格,其中每一行都有一个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。

3 个答案:

答案 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;

请注意,这受最大递归深度的影响,但它可以在四行上正常工作。