SQL如何匹配Text列Fern标记批量填充对应行区间的PONumber列
实现批量填充PONumber列的方案
你原有代码的核心问题
- 循环逻辑写反了:
SET @i = 1放在WHILE判断之后,既没有初始化循环变量,也没有循环内自增变量的逻辑,要么循环不执行,要么直接死循环 - 逐行遍历的效率极低,4000行数据完全可以用集合操作实现,不需要手动划定区间
实现思路
- 定位所有Text包含"Fern"的行,从这类行的文本里按空格拆分,提取第三段值作为对应PO号
- 对每一行,自动匹配该行之前最近的一个含Fern的行的PO号,匹配规则完全符合你要的填充逻辑:比如RowKey=1的Fern行PO是12345678,那么所有RowKey在1到23(即下一个Fern行RowKey=24的前一行)的行,都会自动匹配到这个PO值,不需要手动计算区间
可直接运行的代码
第一步:先验证匹配结果是否正确
先跑查询核对提取的PO值和匹配范围,避免直接更新错数据:
SELECT f.RowKey, f.Text, matchedFern.PONumber_Extracted FROM Flowers f -- 关联匹配最近的上一个Fern行 OUTER APPLY ( SELECT TOP 1 -- 提取Fern行Text的第三个空格分隔值 LTRIM(RTRIM( SUBSTRING( cleanedText, -- 第三段的起始位置:第二个空格的位置+1 CHARINDEX(' ', cleanedText, CHARINDEX(' ', cleanedText) + 1) + 1, -- 第三段的长度:从第二个空格到第三个空格的距离 CHARINDEX(' ', cleanedText, CHARINDEX(' ', cleanedText, CHARINDEX(' ', cleanedText) + 1) + 1) - (CHARINDEX(' ', cleanedText, CHARINDEX(' ', cleanedText) + 1) + 1) ) )) AS PONumber_Extracted FROM ( -- 预处理:把连续多空格替换成单空格,避免切分错位 SELECT REPLACE(FernRow.Text, ' ', ' ') AS cleanedText, FernRow.RowKey FROM Flowers FernRow WHERE CHARINDEX('Fern', FernRow.Text) > 0 ) FernRow WHERE FernRow.RowKey <= f.RowKey ORDER BY FernRow.RowKey DESC -- 取离当前行最近的Fern行 ) matchedFern ORDER BY f.RowKey
注意:如果你的Text里存在3个以上连续空格,把代码里的
REPLACE(FernRow.Text, ' ', ' ')多执行几次替换,直到没有连续空格,比如写成REPLACE(REPLACE(REPLACE(FernRow.Text, ' ', ' '), ' ', ' '), ' ', ' '),保证切分位置准确。
第二步:确认结果无误后执行批量更新
核对完所有匹配关系、提取的PO值都正确后,直接跑UPDATE语句更新PONumber列:
UPDATE target SET PONumber = matchedFern.PONumber_Extracted FROM Flowers target OUTER APPLY ( SELECT TOP 1 LTRIM(RTRIM( SUBSTRING( cleanedText, CHARINDEX(' ', cleanedText, CHARINDEX(' ', cleanedText) + 1) + 1, CHARINDEX(' ', cleanedText, CHARINDEX(' ', cleanedText, CHARINDEX(' ', cleanedText) + 1) + 1) - (CHARINDEX(' ', cleanedText, CHARINDEX(' ', cleanedText) + 1) + 1) ) )) AS PONumber_Extracted FROM ( SELECT REPLACE(REPLACE(REPLACE(FernRow.Text, ' ', ' '), ' ', ' '), ' ', ' ') AS cleanedText, FernRow.RowKey FROM Flowers FernRow WHERE CHARINDEX('Fern', FernRow.Text) > 0 ) FernRow WHERE FernRow.RowKey <= target.RowKey ORDER BY FernRow.RowKey DESC ) matchedFern WHERE matchedFern.PONumber_Extracted IS NOT NULL
方案优势
- 没有循环逻辑,不存在死循环风险,4000行数据执行时间在毫秒级
- 自动匹配填充区间,不需要手动计算每个Fern行对应的上下界
- 提前做了文本预处理,避免连续空格导致的提取值错误
内容的提问来源于stack exchange,提问作者TheCodeLab
相关产品推荐
相关产品推荐

