我有一个包含产品值的表格,如下所示:
苹果手机
iPhone 苹果
三星手机
三星手机
我想从表中删除那些完全相反的产品(因为我认为它们是重复的),这样我的表就只有 2 条记录,而不是 4 条记录
苹果手机
三星手机
我知道SQL Server中有REVERSE函数,但它会反转整个字符串,这不是我正在寻找的。
我非常感谢任何建议/想法。
最佳答案
假设您的字典不包含任何 XML 实体(例如 >
或 <
),并且手动创建一堆 UPDATE
是不切实际的对于表中每个单词组合的语句(如果实用,请简化您的生活,停止阅读此答案,并使用 Justin's answer ),您可以创建一个如下函数:
CREATE FUNCTION dbo.SplitSafeStrings
(
@List NVARCHAR(MAX),
@Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
( SELECT Item = LTRIM(RTRIM(y.i.value('(./text())[1]', 'nvarchar(4000)')))
FROM ( SELECT x = CONVERT(XML, '<i>'
+ REPLACE(@List, @Delimiter, '</i><i>') + '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i));
GO
(如果 XML 存在问题,则 there are other, more complex alternatives ,例如 CLR。)
然后你可以这样做:
DECLARE @x TABLE(id INT IDENTITY(1,1), s VARCHAR(64));
INSERT @x(s) VALUES
('apple iphone'),
('iphone Apple'),
('iphone samsung hoochie blat'),
('samsung hoochie blat iphone');
;WITH cte1 AS
(
SELECT id, Item FROM @x AS x
CROSS APPLY dbo.SplitSafeStrings(LOWER(x.s), ' ') AS y
),
cte2(id,words) AS
(
SELECT DISTINCT id, STUFF((SELECT ',' + orig.Item
FROM cte1 AS orig
WHERE orig.id = cte1.id
ORDER BY orig.Item
FOR XML PATH(''), TYPE).value('.[1]','nvarchar(max)'),1,1,'')
FROM cte1
),
cte3 AS
(
SELECT id, words, rn = ROW_NUMBER() OVER (PARTITION BY words ORDER BY id)
FROM cte2
)
SELECT id, words, rn FROM cte3
-- WHERE rn = 1 -- rows to keep
-- WHERE rn > 1 -- rows to delete
;
所以你可以在三个 CTE 之后,而不是最后的 SELECT
在上面,说:
DELETE t FROM @x AS t
INNER JOIN cte3 ON cte3.id = t.id
WHERE cte3.rn > 1;
@x
中应该留下什么?
SELECT id, s FROM @x;
结果:
id s
-- ---------------------------
1 apple iphone
3 iphone samsung hoochie blat
关于sql - SQL Server 中的反转字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18409034/