获取前一行的 ID,该行的 ID 并不总是在相关行之前的静态行数?
Get the ID of a previous row that is not always a static number of rows before the row in question?
我知道我的问题听起来很笼统,但我无法在不写一段话的情况下指定标题中的所有细节。我会尽量在这里直截了当。
我有一个 forms/ordered form-items 的数据库 table。每个form-item可以缩进某个'level'。例如,缩进级别 (IL) = 0 的所有行都是该表单上的 top-level 项。如果 IL = 1,并且直接出现在 IL = 0 行之后,则 IL1 行的 parent 将是前一个 IL0 行。但是,可以有 X 个 IL1 项目,它们的 parent 都是相同的前一个 IL0。这种模式可以继续向下到 6 层嵌套(其中 IL6 的 parent 将是之前的 IL5)
这是一个表单示例,其中包含我手动填写的正确 ParentItemID(这是我尝试动态计算的列):
ItemID FormID SortOrder Indent Description ParentItemID
1000 1 1 0 Main Item 1 NULL
1001 1 2 0 Main Item 2 NULL
1002 1 3 1 Sub Item 1 1001
1003 1 4 1 Sub Item 2 1001
1004 1 5 2 Sub Item 2-1 1003
1005 1 6 2 Sub Item 2-2 1003
1006 1 7 2 Sub Item 2-3 1003
1007 1 8 3 Sub Item 2-3-1 1006
1008 1 9 1 Sub Item 3 1001
1009 1 10 0 Main Item 3 NULL
下面是将数据库中的原始数据实际转换为表格时的样子,就像一个可视化示例:
我正在尝试使用 LAG,它适用于第一个 IL1 项目,但从那里开始,以下每个项目都引用前一行。我想我可以 运行 一堆更新,过滤到每个缩进级别,但这并不理想。我看到 LAG 采用偏移参数,但出于某种原因,我无法理解如何动态计算它以始终引用缩进级别小于 1 的前一个项目(基于排序顺序)当前缩进级别。
这是创建 table 并填充数据的 sql:
create table FormItems(
ItemID int,
FormID int,
SortOrder int,
Indent int,
Description nvarchar(100),
ParentItemID int
)
insert into FormItems
select 1000, 1, 1 , 0, 'Main Item 1' ,NULL union
select 1001, 1, 2 , 0, 'Main Item 2' ,NULL union
select 1002, 1, 3 , 1, 'Sub Item 1' ,1001 union
select 1003, 1, 4 , 1, 'Sub Item 2' ,1001 union
select 1004, 1, 5 , 2, 'Sub Item 2-1' ,1003 union
select 1005, 1, 6 , 2, 'Sub Item 2-2' ,1003 union
select 1006, 1, 7 , 2, 'Sub Item 2-3' ,1003 union
select 1007, 1, 8 , 3, 'Sub Item 2-3-1' ,1006 union
select 1008, 1, 9 , 1, 'Sub Item 3' ,1001 union
select 1009, 1, 10, 0, 'Main Item 3' ,NULL
可能最简单的方法是应用:
select t.*, tp.itemId
from t outer apply
(select top (1) tp.*
from t tp
where tp.formId = t.formId and
tp.indent = t.indent - 1 and
tp.sortorder < t.sortorder
order by tp.sortorder desc
) tp;
我知道我的问题听起来很笼统,但我无法在不写一段话的情况下指定标题中的所有细节。我会尽量在这里直截了当。
我有一个 forms/ordered form-items 的数据库 table。每个form-item可以缩进某个'level'。例如,缩进级别 (IL) = 0 的所有行都是该表单上的 top-level 项。如果 IL = 1,并且直接出现在 IL = 0 行之后,则 IL1 行的 parent 将是前一个 IL0 行。但是,可以有 X 个 IL1 项目,它们的 parent 都是相同的前一个 IL0。这种模式可以继续向下到 6 层嵌套(其中 IL6 的 parent 将是之前的 IL5)
这是一个表单示例,其中包含我手动填写的正确 ParentItemID(这是我尝试动态计算的列):
ItemID FormID SortOrder Indent Description ParentItemID
1000 1 1 0 Main Item 1 NULL
1001 1 2 0 Main Item 2 NULL
1002 1 3 1 Sub Item 1 1001
1003 1 4 1 Sub Item 2 1001
1004 1 5 2 Sub Item 2-1 1003
1005 1 6 2 Sub Item 2-2 1003
1006 1 7 2 Sub Item 2-3 1003
1007 1 8 3 Sub Item 2-3-1 1006
1008 1 9 1 Sub Item 3 1001
1009 1 10 0 Main Item 3 NULL
下面是将数据库中的原始数据实际转换为表格时的样子,就像一个可视化示例:
我正在尝试使用 LAG,它适用于第一个 IL1 项目,但从那里开始,以下每个项目都引用前一行。我想我可以 运行 一堆更新,过滤到每个缩进级别,但这并不理想。我看到 LAG 采用偏移参数,但出于某种原因,我无法理解如何动态计算它以始终引用缩进级别小于 1 的前一个项目(基于排序顺序)当前缩进级别。
这是创建 table 并填充数据的 sql:
create table FormItems(
ItemID int,
FormID int,
SortOrder int,
Indent int,
Description nvarchar(100),
ParentItemID int
)
insert into FormItems
select 1000, 1, 1 , 0, 'Main Item 1' ,NULL union
select 1001, 1, 2 , 0, 'Main Item 2' ,NULL union
select 1002, 1, 3 , 1, 'Sub Item 1' ,1001 union
select 1003, 1, 4 , 1, 'Sub Item 2' ,1001 union
select 1004, 1, 5 , 2, 'Sub Item 2-1' ,1003 union
select 1005, 1, 6 , 2, 'Sub Item 2-2' ,1003 union
select 1006, 1, 7 , 2, 'Sub Item 2-3' ,1003 union
select 1007, 1, 8 , 3, 'Sub Item 2-3-1' ,1006 union
select 1008, 1, 9 , 1, 'Sub Item 3' ,1001 union
select 1009, 1, 10, 0, 'Main Item 3' ,NULL
可能最简单的方法是应用:
select t.*, tp.itemId
from t outer apply
(select top (1) tp.*
from t tp
where tp.formId = t.formId and
tp.indent = t.indent - 1 and
tp.sortorder < t.sortorder
order by tp.sortorder desc
) tp;