按 Start/End 列排序
Order by Start/End Columns
我正在尝试对具有两列 StartStep
和 EndStep
(文本列)的 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
没有EndStep
的StartStep
排在第一位,然后沿着路径向下排序,这样下一个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 行
我正在尝试对具有两列 StartStep
和 EndStep
(文本列)的 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
没有EndStep
的StartStep
排在第一位,然后沿着路径向下排序,这样下一个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 行