表:l_test1
CREATE TABLE l_test1
(
Cola VARCHAR(10)
);
表:l_test2
CREATE TABLE l_test2
(
Cola VARCHAR(20)
);
插入:
INSERT INTO l_test1 VALUES('1');
INSERT INTO l_test1 VALUES('12');
INSERT INTO l_test1 VALUES('123');
INSERT INTO l_test1 VALUES('1234');
INSERT INTO l_test2 VALUES('991234567890');
INSERT INTO l_test2 VALUES('9912345678901');
INSERT INTO l_test2 VALUES('99123456789012');
INSERT INTO l_test2 VALUES('123991234567890');
INSERT INTO l_test2 VALUES('981234567890');
INSERT INTO l_test2 VALUES('1234991234567890');
INSERT INTO l_test2 VALUES('1981234567890');
注意:现在我要删除与数字匹配的表l_test2
的起始和结束数字
列于表l_test1
中。
例如:在上表中,我在表1,12,123,1234
中有l_test1
个值。现在我想要
删除与这些数字匹配的表l_test2
的值。第二个记录
表格l_test2
与表格1
中的值l_test1
匹配,因此应将其删除。
更新所有值后,表l_test2
应如下所示:
预期结果:
Cola
---------------------------
991234567890
991234567890
991234567890
991234567890
981234567890
991234567890
981234567890
答案 0 :(得分:3)
使用STUFF
:
<强> LiveDemo 强>
WITH cte1 AS
(
SELECT t2.Cola, MAX(t1.Cola) AS r
FROM #l_test2 t2
JOIN #l_test1 t1
ON t2.Cola LIKE t1.Cola + '%'
GROUP BY t2.Cola
),
cte2 AS
(
SELECT t2.Cola, MAX(t1.Cola) AS r
FROM #l_test2 t2
JOIN #l_test1 t1
ON t2.Cola LIKE '%' + t1.Cola
GROUP BY t2.Cola
), cte3 AS
(
SELECT Cola, STUFF(Cola, 1, LEN(r), '') AS sanitized
FROM cte1
UNION ALL
SELECT Cola, STUFF(Cola, LEN(Cola) - LEN(r) + 1, LEN(r), '') AS sanitized
FROM cte2
)
SELECT sanitized
FROM cte3
UNION ALL
SELECT Cola
FROM #l_test2 t
WHERE NOT EXISTS (SELECT 1 FROM cte3 c3 WHERE c3.Cola = t.Cola);
为了便于阅读,我将其分为几部分:
随意将我的解决方案组合成更简洁的方式;)
答案 1 :(得分:0)
我想不出一个简单的方法。这是一种尝试删除所有组合然后查找最短结果值的方法:
{{1}}
答案 2 :(得分:0)
您可以使用以下使用PATINDEX
的查询:
SELECT DISTINCT
Cola,
SUBSTRING(Cola, left_index + 1, right_index - left_index - 1) AS sanitized_Cola
FROM (
SELECT MAX(CASE WHEN t3.left_match = 1 THEN LEN(t1.Cola) ELSE 0 END)
OVER (PARTITION BY t2.Cola) AS left_index,
MIN(CASE WHEN right_match = 0 THEN LEN(t2.Cola)+1 ELSE right_match END)
OVER (PARTITION BY t2.Cola) AS right_index,
t2.Cola
FROM l_test2 AS t2
CROSS JOIN l_test1 AS t1
CROSS APPLY (SELECT PATINDEX(t1.Cola + '%', t2.Cola) AS left_match) AS t3
CROSS APPLY (SELECT PATINDEX('%' + t1.Cola, t2.Cola) AS right_match) AS t4 ) AS q
我们的想法是左右和右边找到最大匹配模式(如果有的话)。然后在SUBSTRING
中使用这些匹配的索引来获取已清理的字符串。
答案 3 :(得分:0)
;WITH CTE AS
(
SELECT L2.Cola, max(L1.Cola) AS substr ,'pre' as Flag
FROM l_test1 L1 INNER JOIN l_test2 L2 ON L2.Cola LIKE L1.Cola+'%'
group by L2.Cola
union all
SELECT L2.Cola, max(L1.Cola) AS substr ,'post' as Flag
FROM l_test1 L1 INNER JOIN l_test2 L2 ON L2.Cola LIKE '%'+L1.Cola
group by L2.Cola
)
update l2
set Cola = SUBSTRING(cte.Cola,case Flag when 'pre' then len(substr) + 1 else 1 end,
len(cte.cola) - len(substr))
from l_test2 l2 inner join cte on l2.Cola = cte.Cola;
获取最大匹配字符串和此匹配字符串的len的一个CTE。