按 Start/End 列排序

Order by Start/End Columns

我正在尝试对具有两列 StartStepEndStep(文本列)的 table 进行排序,如下所示:

ObjectName | StepName      | StartStep     | EndStep
-----------+---------------+---------------+-------------
Obj1       | FirstStep     | NULL          | SecondStep
Obj1       | SecondStep    | FirstStep     | NextStep
Obj1       | NextStep      | SecondStep    | FourthStep
Obj1       | FourthStep    | NextStep      | NULL
Obj2       | SomethingElse | NULL          | AfterThat

等...

我需要排序,使每个ObjectName没有EndStepStartStep排在第一位,然后沿着路径向下排序,这样下一个StartStep是前一条记录的EndStep

使用 SQL Server 2014,所以我想可能使用 LAG/LEAD 进行某种类型的排序...但我迷路了。

我已经搜索过,但没有直接找到任何内容,所以如果您将其标记为重复,请将 link 提供给 "duplicate" post - 显然我'否则我没有使用正确的搜索词。请帮忙!

假设你已经或将要添加一个序列,这就变成了lead() over()

的小事

示例 -- 请注意 Seq 列

Declare @YourTable Table ([Seq] Int,[ObjectName] varchar(50),[StepName] varchar(50))
Insert Into @YourTable Values 
 (1,'Obj1','FirstStep')
,(2,'Obj1','SecondStep')
,(3,'Obj1','NextStep')
,(4,'Obj1','FourthStep')
,(1,'Obj2','SomethingElse')

Select *  
      ,StartStep  = StepName
      ,EndStep    = lead(StepName,1) over (Partition By ObjectName Order by Seq)
 From @YourTable
 Order By ObjectName,Seq

Returns

Seq ObjectName  StepName        StartStep       EndStep
1   Obj1        FirstStep       FirstStep       SecondStep
2   Obj1        SecondStep      SecondStep      NextStep
3   Obj1        NextStep        NextStep        FourthStep
4   Obj1        FourthStep      FourthStep      NULL
1   Obj2        SomethingElse   SomethingElse   NULL

你也可以使用案例

  select  * 
  from  my_table  

  order by  case when endstep  is null  then 0 else  1 end asc , startStep , endStep  

听起来你想要递归的东西:

CREATE TABLE d
    ([ObjectName] varchar(4), [StepName] varchar(13), [StartStep] varchar(13), [EndStep] varchar(10))
;

INSERT INTO d
    ([ObjectName], [StepName], [StartStep], [EndStep])
VALUES
    ('Obj1', 'FourthStep', 'FourthStep', NULL),
    ('Obj1', 'FirstStep', 'FirstStep', 'SecondStep'),
    ('Obj1', 'NextStep', 'NextStep', 'FourthStep'),
    ('Obj1', 'SecondStep', 'SecondStep', 'NextStep'),
    ('Obj2', 'SomethingElse', 'SomethingElse', 'AfterThat')
;

with cte as
(
select 0 as level, objectname, stepname, startstep, endstep from d where endstep is null
union all
select level + 1 as level, d.objectname, d.stepname, d.startstep, d.endstep from d inner join cte on cte.startstep = d.endstep
)


select * from cte order by objectname, level 

希望递归的步骤不会超过 SQLS 的能力(默认为 100 步)

这里我实际上是反向构建树,从最后一步(endstep 为空)回到第一步,在我走的时候保持一个级别计数器。我这样做是因为在递归查询中不允许外连接,并且在 startstep=endstep 谓词中获取 null 的一种简单方法是从 endstep 为 null 的行开始并向后工作(因此连接永远不必操作endstep 为空的行)。对级别进行升序排序会将行按照您要求的顺序排列(任何给定的行都取决于 row-below-it 样式)。如果您按 level desc 订购,您会看到 "order of operation" 样式

此查询省略了您的 Obj2,因为它没有空结束步骤。我认为这是因为您的问题

中缺少 obj2 行