我希望使用 LAG 函数沿着表内容的长度重复填充字段。这是我的情况。我正在从一个笨拙的源读取数据,该源提取看起来像这样的行 --
Split_Name_In_Heading ID
Central Scheduling (contd) 171081
NULL 171083
NULL 171088
NULL 171091
NULL 171094
NULL 171097
有数千个这样的字段,其中我有兴趣抓取的字段,Split_Name_In_Heading,并将其级联到后面的所有记录。我想执行此操作,直到找到新的 Split_Name_In_Heading,然后开始复制该名称。所以我这样做了--
select
case when Split_Name_In_Heading is null
then lag(Split_Name) over (order by ID)
else REPLACE(SPLIT_NAME_IN_HEADING, ' (contd)', '') end as Split_Name,
Split_Name_In_Heading,
ID
--into #Pass_1
from #Clean_List
order by ID
请注意,我正在尝试创建一个新字段 Split_Name,它引用前一行的 Split_Name。它是自我引用的。 (它也删除了 Split_Name_In_Heading 字段末尾的垃圾,但这很好)我想要的结果 --
Split_Name Split_Name_In_Heading ID
Central Scheduling Central Scheduling (contd) 171081
Central Scheduling NULL 171083
Central Scheduling NULL 171088
Central Scheduling NULL 171091
Central Scheduling NULL 171094
Central Scheduling NULL 171097
我的代码产生错误。我无法在字段 Split_Name 的定义中引用字段 Split_Name。当我尝试使用 Split_Name_In_Heading 引导加载第二遍的值时,它只会为后续一条记录创建值。之后这些值保持为空。
这是从 WebFOCUS 代码进行的转换,这是一件超级简单的事情,我们已经在代码库中完成了数十次,所以我正在寻找一个通用的解决方案。我需要全部更换。 LAG 可以以某种方式自引用自己的字段吗?我已经看到几个线程使用临时表和前一行的引用,但我还没有找到一种简单的方法来实现这一点,因为它们不会继续将值复制到多行集合中有空值的。有时可能高达 100。
假设ID是这里的SEQUENCE,我们可以使用窗口函数
sum() over ()
来创建分组,然后我们使用窗口函数max() over()
作为最终值
示例
Declare @YourTable Table ([Split_Name_In_Heading] varchar(50),[ID] int) Insert Into @YourTable Values
('Central Scheduling (cont''d)',171081)
,(NULL,171083)
,(NULL,171088)
,(NULL,171091)
,(NULL,171094)
,(NULL,171097)
,('Other Item (cont''d)',181081) -- added another example
,(NULL,181083); -- added another example
with cte as (
Select *
,Flg = sum(case when [Split_Name_In_Heading] is not null then 1 else 0 end) over (order by ID)
from @YourTable
)
Select Split_Name = replace(max([Split_Name_In_Heading]) over (partition by Flg),' (cont''d)','')
,[Split_Name_In_Heading]
,ID
From cte
Order by ID
结果
Split_Name Split_Name_In_Heading ID
Central Scheduling Central Scheduling (cont'd) 171081
Central Scheduling NULL 171083
Central Scheduling NULL 171088
Central Scheduling NULL 171091
Central Scheduling NULL 171094
Central Scheduling NULL 171097
Other Item Other Item (cont'd) 181081
Other Item NULL 181083
您可以在此处实现一个简单的相关子查询作为表表达式,然后您可以更新该表表达式。
示例:
update t set
name = NewName
from (
select *, (
select top(1) name
from t t2
where t2.name is not null and t2.id < t.id
order by id desc
) NewName
from t
where name is null
)t;
查看演示小提琴