Упорядочить по столбцам начала / конца - PullRequest
0 голосов
/ 25 января 2019

Я пытаюсь отсортировать таблицу с двумя столбцами StartStep & EndStep (текстовые столбцы) следующим образом:

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

и т. Д.

Iнужно отсортировать так, чтобы StartStep без EndStep для каждого ObjectName был первым, а затем следовать по пути вниз, чтобы следующий StartStep был EndStep предыдущей записи.

Использование SQL Server 2014, так что я думаю, возможно, какой-то тип сортировки с использованием LAG/LEAD ... но я потерян.

Я искал, но ничего не нашел прямо наЕсли вы отметите это как дубликат, предоставьте ссылку на «дубликат» сообщения - в противном случае я не буду использовать правильные условия поиска.Пожалуйста, помогите!

Ответы [ 3 ]

0 голосов
/ 25 января 2019

Вы также можете использовать чехол

  select  * 
  from  my_table  

  order by  case when endstep  is null  then 0 else  1 end asc , startStep , endStep  
0 голосов
/ 25 января 2019

Звучит так, будто вы хотите что-то рекурсивное:

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 состоит в том, чтобы начать со строки, где EndStep равен NULL, и работать в обратном направлении (поэтому объединение никогда не должно работать сстрока, в которой конечный шаг равен нулю).Сортировка по возрастанию уровня приводит строки в требуемом порядке (любая строка зависит от стиля row-under-it).Если вы сделаете заказ по level desc, вы увидите их в стиле «порядок работы»

. В этом запросе ваш Obj2 опущен, поскольку он не имеет нулевого конечного шага.Я предполагаю, что это потому, что в вашем вопросе отсутствуют строки obj2

0 голосов
/ 25 января 2019

Если у вас есть или будет добавлена ​​последовательность, она становится незначительной величиной 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
...