我正在使用 Microsoft SQL Server 2019 15.0.4360.2 (X64)
假设我的 SQL 服务器中有一个表
代码 | 关键字 | 描述 | 组件_键 |
---|---|---|---|
A1 | 莎莉 | 莎莉:玛丽是她的女儿 | |
A2 | 玛丽 | 玛丽:约翰是她的妹妹,莎莉是她的母亲 | |
A3 | 简 | 简:约翰是她的伴侣 | |
A4 | 约翰 | 约翰:简是他的伴侣,莎莉是他的母亲,玛丽是他的妹妹。玛丽不是他的伴侣 |
我想找到一种动态更新 Component_Keys 的方法,以便它循环遍历每个描述,识别描述中的关键字实例,如果找到关键字实例,则将代码记录在 Component_Keys 列中。如果某个关键字在描述中出现多次,我希望它在 Component_Keys 中只出现一次。如果出现多个关键字我希望将其记录为Code1+Code2+Code3.....
最后,如果描述中的关键字位于同一行,我希望它忽略它。
因此更新查询的输出将如下所示
代码 | 关键字 | 描述 | 组件_键 |
---|---|---|---|
A1 | 莎莉 | 莎莉:玛丽是她的女儿 | A2 |
A2 | 玛丽 | 玛丽:约翰是她的妹妹,莎莉是她的母亲 | A4+A1 |
A3 | 简 | 简:约翰是她的伴侣 | A4 |
A4 | 约翰 | 约翰:简是他的伴侣,莎莉是他的母亲,玛丽是他的妹妹。玛丽不是他的伴侣 | A3+A1+A2 |
到目前为止我有以下代码
IF OBJECT_ID(N'tempdb..#temp') IS NOT NULL
BEGIN -- Checking to ensure temp table does not exist, and dropping anyone that does to avoid errors
DROP TABLE #temp;
END;
GO
--- Create Temp Table to store values and manipulate before inserting into production table ----
CREATE TABLE #temp
(
Code VARCHAR(MAX)
, Keyword VARCHAR(MAX)
, Description VARCHAR(MAX)
, Component_Keys VARCHAR(MAX)
);
INSERT INTO #temp (Code
, Keyword
, Description
, Component_Keys)
VALUES ('A1', 'Sally', 'Sally : Mary is her Daughter', NULL)
, ('A2', 'Mary', 'Mary : John is her sister and sally is her mother', NULL)
, ('A3', 'Jane', 'Jane : John is her partner', NULL)
, ('A4', 'John'
, 'John : Jane is his partner and Sally is his mother and Mary is his sister. Mary is not his partner', NULL);
SELECT *
FROM #temp;
-- Creating Variables
DECLARE @DKeyword VARCHAR(MAX); -- Declaring Dynamic Keyword Variable
DECLARE @DUpdateStatement VARCHAR(MAX); ---Declaring Dynamic Update Statement Variable
DECLARE @DCode VARCHAR(MAX) -- Declaring Dynamic Code Variable
SELECT @DKeyword= Keyword, @DCode=code
FROM #temp
更新#temp 设置 Component_Keys = @DUpdateStatement
我不确定如何从这里继续进行以下操作:
我不太明白如何在这里起草更新语句变量,这样
对于每一行,您需要:
UPDATE T
SET Component_Keys = (
SELECT STRING_AGG(T2.Code, '+') WITHIN GROUP(ORDER BY P.Pos)
FROM #temp T2
CROSS APPLY(SELECT CHARINDEX(T2.Keyword, T.Description) AS Pos) P
WHERE T2.Code <> T.Code
AND P.Pos >= 1
)
FROM #temp T
您还可以使用
CROSS APPLY
将计算与 SET
子句分开,有些人可能会觉得这样更具可读性。
UPDATE T
SET Component_Keys = C.CalculatedKeys
FROM #temp T
CROSS APPLY (
SELECT STRING_AGG(T2.Code, '+') WITHIN GROUP(ORDER BY P.Pos) AS CalculatedKeys
FROM #temp T2
CROSS APPLY(SELECT CHARINDEX(T2.Keyword, T.Description) AS Pos) P
WHERE T2.Code <> T.Code
AND P.Pos >= 1
) C
两者的结果相同:
代码 | 关键字 | 描述 | 组件_键 |
---|---|---|---|
A1 | 莎莉 | 莎莉:玛丽是她的女儿 | A2 |
A2 | 玛丽 | 玛丽:约翰是她的妹妹,莎莉是她的母亲 | A4+A1 |
A3 | 简 | 简:约翰是她的伴侣 | A4 |
A4 | 约翰 | 约翰:简是他的伴侣,莎莉是他的母亲,玛丽是他的妹妹。玛丽不是他的伴侣 | A3+A1+A2 |
请参阅 this db<>fiddle 进行演示。