[英]SQL insert value into column on a specific match
I have a table consisting of roughly 4000 rows.我有一张由大约 4000 行组成的表格。 I am parsing through the column Text
in the table and finding every instance of the word 'Fern' and from that the value in the third position of the string I am placing into another column named PONumber
.我正在解析表中的Text
列,并找到单词“Fern”的每个实例,并从中找到我放入另一列名为PONumber
的字符串的第三个 position 中的值。 My third column RowKey
is an identity column and tells me what rows the word I am searching for is on.我的第三列RowKey
是一个标识列,它告诉我要搜索的单词在哪些行上。
For example the first instance of the word Fern is on row 1 while the next instance is on row 24. I am trying to get the value from the first instance into the PONumber
column from row 1-23.例如,单词 Fern 的第一个实例位于第 1 行,而下一个实例位于第 24 行。我试图将第一个实例的值放入第 1-23 行的PONumber
列中。 The next instance is on row 24 and ends on row 28, so I would need that value in the PONumber
column on rows 24-28 and so on....下一个实例位于第 24 行并在第 28 行结束,因此我需要第 24-28 行的PONumber
列中的该值,依此类推......
I am having trouble selecting only that range and placing the value into the corresponding rows in the PONumber
column我无法仅选择该范围并将值放入PONumber
列中的相应行
My code so far:到目前为止我的代码:
DECLARE @i INT, @maxCount INT;
select @maxCount = max(RowKey) from Flowers
WHILE @i <= @maxCount
SET @i = 1;
BEGIN
SELECT Text, PONumber, RowKey FROM Flowers
WHERE CHARINDEX('Fern', Text) > 0
'I need to grab that value and INSERT INTO Number column
END
Sample Data:样本数据:
Text PONumber
1 Fern Flower 12345678 More text 12345678
. 12345678
. 12345678
. 12345678
. 12345678
. 12345678
.
23
24 Fern Flower 23456789 More text PONumber
. 23456789
. 23456789
. 23456789
. 23456789
29
Considering that all the values are prefixed with 'text'
then is seems you could just use CHARINDEX
and STUFF
to remove that section of text:考虑到所有值都以'text'
为前缀,那么您似乎可以只使用CHARINDEX
和STUFF
来删除该部分文本:
SELECT STUFF(YourColumn,1,NULLIF(CHARINDEX('text',YourColumn),0)+5,'') AS PONumber
FROM dbo.YourTable;
Edit: Based on the latest version, then it's not 'text'
it's 'Fern Flower'
and then you just need the left most characters to the next space (or end of the value?):编辑:根据最新版本,它不是'text'
而是'Fern Flower'
,然后你只需要最左边的字符到下一个空格(或值的末尾?):
SELECT YT.YourColumn,
LEFT(STUFF(YT.YourColumn,1,CI1.I-1,''),CI2.I - CI1.I) AS PONumber
FROM dbo.YourTable YT
CROSS APPLY (VALUES(NULLIF(CHARINDEX('Fern Flower',YT.YourColumn),0)+LEN('Fern Flower') + 1))CI1(I)
CROSS APPLY (VALUES(ISNULL(NULLIF(CHARINDEX(' ',YT.YourColumn,CI1.I),0),LEN(YT.YourColumn))))CI2(I);
These types of situations are tricky and can be a real bear to wrestle with.这些类型的情况很棘手,可能是一个真正的熊。
My first note is to consider adding a PONumber column to your data and capturing that upon insert vs parsing text.我的第一个注意事项是考虑在您的数据中添加一个 PONumber 列,并在插入和解析文本时捕获它。 Having said that, here's an idea to address your current need.话虽如此,这里有一个解决您当前需求的想法。
First, here's a function designed to parse your "fern" po number from a text value:首先,这是一个 function 旨在从文本值解析您的“蕨类”po 编号:
CREATE FUNCTION dbo.GetPO (
@text varchar(8000)
)
RETURNS varchar(255)
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
DECLARE
@pos int = CHARINDEX ( 'fern', @text ),
@po varchar(255);
IF @pos > 0 BEGIN
-- Locate the starting position of the first numeric value.
-- Ass-u-mes *any* numeric value following the word "fern" is the expected po.
WHILE ISNUMERIC ( SUBSTRING ( @text, @pos, 1 ) ) = 0 AND @pos <= LEN ( @text )
SET @pos = @pos + 1;
-- If @pos is not equal to @text's length then assume a @po value was found.
IF @pos < LEN ( @text ) BEGIN
WHILE ISNUMERIC ( SUBSTRING ( @text, @pos, 1 ) ) = 1 BEGIN
SET @po = ISNULL ( @po, '' ) + SUBSTRING ( @text, @pos, 1 );
SET @pos = @pos + 1;
END
END
END
RETURN @po;
END
GO
Running SELECT dbo.GetPO ( 'Fern Flower 12345678 More text' );
运行SELECT dbo.GetPO ( 'Fern Flower 12345678 More text' );
returns 12345678
.返回12345678
。
Next, to continue your previous PONumber in the event GetPO
returned NULL
, here is an example how you might go about that using dbo.GetPO
:接下来,要在GetPO
返回NULL
的情况下继续您之前的 PONumber,这里是一个示例,您可以如何使用 dbo.GetPO 进行dbo.GetPO
:
DECLARE @Data table ( [Text] varchar(8000), RowKey int IDENTITY (1,1) );
INSERT INTO @Data VALUES
( 'Fern Flower 12345678 More text' ),
( '.' ),
( '.' ),
( 'Fern Flower 23456789 More text' ),
( '.' );
;WITH cte AS (
SELECT
RowKey,
[Text],
dbo.GetPO ( [Text] ) AS PONumber
FROM @Data
)
SELECT
RowKey,
[Text],
CASE
WHEN PONumber IS NULL THEN (
-- Get the most recent non-null PONumber.
SELECT TOP 1 PONumber FROM cte AS x WHERE x.RowKey < cte.RowKey AND x.PONumber IS NOT NULL ORDER BY x.RowKey DESC
)
ELSE PONumber -- Keep the existing PONumber.
END AS PONumber
FROM cte
ORDER BY RowKey;
Returns退货
+--------+---------------------------------+----------+
| RowKey | Text | PONumber |
+--------+---------------------------------+----------+
| 1 | Fern Flower 12345678 More text | 12345678 |
| 2 | . | 12345678 |
| 3 | . | 12345678 |
| 4 | Fern Flower 23456789 More text | 23456789 |
| 5 | . | 23456789 |
+--------+---------------------------------+----------+
UPDATE更新
Here's an example of continuing your PONumber across NULL values using a combination of my and @Larnu's examples:这是使用我和@Larnu 的示例组合在 NULL 值中继续您的 PONumber 的示例:
;WITH cte AS (
SELECT
RowKey,
[Text],
LEFT( STUFF( YT.[Text], 1, CI1.I-1, '' ), CI2.I - CI1.I ) AS PONumber
FROM @Data YT
CROSS APPLY (
VALUES ( NULLIF ( CHARINDEX ( 'Fern Flower', YT.[Text] ), 0 ) + LEN ( 'Fern Flower' ) + 1 )
) CI1 ( I )
CROSS APPLY (
VALUES ( ISNULL ( NULLIF ( CHARINDEX ( ' ', YT.[Text], CI1.I ), 0 ), LEN ( YT.[Text] ) ) )
) CI2 ( I )
)
SELECT
RowKey,
[Text],
CASE
WHEN PONumber IS NULL THEN (
-- Get the most recent non-null PONumber.
SELECT TOP 1 PONumber FROM cte AS x WHERE x.RowKey < cte.RowKey AND x.PONumber IS NOT NULL ORDER BY x.RowKey DESC
)
ELSE PONumber -- Keep the existing PONumber.
END AS PONumber
FROM cte
ORDER BY RowKey;
Returns退货
+--------+---------------------------------+----------+
| RowKey | Text | PONumber |
+--------+---------------------------------+----------+
| 1 | Fern Flower 12345678 More text | 12345678 |
| 2 | . | 12345678 |
| 3 | . | 12345678 |
| 4 | Fern Flower 23456789 More text | 23456789 |
| 5 | . | 23456789 |
+--------+---------------------------------+----------+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.