按开始/结束列排序

时间:2019-01-25 17:14:22

标签: sql sql-server sql-server-2014

我正在尝试对具有两列StartStepEndStep(文本列)的表进行排序:

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

等...

我需要进行排序,以使每个StartStep都没有EndStep的{​​{1}}是第一个,然后沿着路径向下移动,以便下一个ObjectName是{先前记录的{1}}。

使用SQL Server 2014,所以我在考虑使用StartStep进行某种类型的排序...但是我迷路了。

我已经搜索了,但没有直接找到任何东西,因此,如果将其标记为重复,请提供指向“重复”帖子的链接-显然,我没有使用正确的搜索词。请帮忙!

3 个答案:

答案 0 :(得分:2)

假设您拥有或将要添加一个序列,这将成为lead() over()

的一个小问题

示例-请注意“序列”列

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

返回

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

答案 1 :(得分:1)

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

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个步骤)

在这里,我实际上是反向构建树,从最后一步(结束步骤为null)回到第一步,并在进行过程中保持级别计数器。我这样做是因为在递归查询中不允许外部联接,并且在startstep = endstep谓词中获取null的一种简单方法是从endstep为null的行开始并向后工作(因此联接不必在endstep为null的行)。对级别进行升序排序将使行按您要求的顺序排列(任何给定的行都取决于其下方的样式)。如果您按level desc订购,则会以“操作顺序”样式看到它们

此查询省略了您的Obj2,因为它没有空的最终步骤。我想是因为您的问题中缺少obj2行

答案 2 :(得分:0)

您还可以使用案例

  select  * 
  from  my_table  

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