我不知道该如何表达这个问题,但可以使用一个示例。所以我有这张桌子
Users
Id Name
1 Tim
2 Jon
3 Matt
还有另一张桌子
Tags
TagId TagName
1 Test
2 Other
3 Dummy
4 More
在临时表中,我有这样的结构
TmpUserTags
User Tags
Tim Test
Jon Other, Test
Matt Dummy, More, Other
所以,我需要做的是从此临时表中,在表中插入UserTags
具有相应ID的记录,对于上面给出的示例,结果将是
UserTags
User TagId
1 1
2 2
2 1
3 3
3 4
3 2
因此,这是我想要插入的最终结果UserTags
。但是,由于TmpUserTags
每个用户的每一行都可以有许多用逗号分隔的标签,因此我不知道哪种方法是最好的。我可能可以使用while循环(或更确切地说是一个游标)循环遍历中的所有行TmpUserTags
,然后针对每一行,以逗号分隔标记,找到其ID,然后将其插入UserTags
。但这似乎并不是最优化的方法。有人可以建议一些更好的方法吗?
我认为最简单的方法是使用来加入标签列LIKE
:
CREATE TABLE #Users (ID INT, Name VARCHAR(4));
INSERT #Users (ID, Name)
VALUES (1, 'Tim'), (2, 'Jon'), (3, 'Matt');
CREATE TABLE #Tags (TagID INT, TagName VARCHAR(5));
INSERT #Tags (TagID, TagName)
VALUES (1, 'Test'), (2, 'Other'), (3, 'Dummy'), (4, 'More');
CREATE TABLE #TmpUserTags ([User] VARCHAR(4), Tags VARCHAR(100));
INSERT #tmpUserTags ([User], Tags)
VALUES ('Tim', 'Test'), ('Jon', 'Other,Test'), ('Matt', 'Dummy,More,Other');
SELECT u.ID, t.TagID
FROM #TmpUserTags AS ut
INNER JOIN #Users AS u
ON u.Name = ut.[User]
INNER JOIN #Tags AS t
ON ',' + ut.Tags + ',' LIKE '%,' + t.TagName + ',%';
您也可以沿着创建拆分功能的路线进行操作,以将逗号分隔的列表拆分为行:
CREATE FUNCTION [dbo].[Split](@StringToSplit NVARCHAR(MAX), @Delimiter NCHAR(1))
RETURNS TABLE
AS
RETURN
(
SELECT ID = ROW_NUMBER() OVER(ORDER BY n.Number),
Position = Number,
Value = SUBSTRING(@StringToSplit, Number, CHARINDEX(@Delimiter, @StringToSplit + @Delimiter, Number) - Number)
FROM ( SELECT TOP (LEN(@StringToSplit) + 1) Number = ROW_NUMBER() OVER(ORDER BY a.object_id)
FROM sys.all_objects a
) n
WHERE SUBSTRING(@Delimiter + @StringToSplit + @Delimiter, n.Number, 1) = @Delimiter
);
然后,您可以使用:
SELECT u.ID, t.TagID
FROM #TmpUserTags AS ut
CROSS APPLY dbo.Split(ut.tags, ',') AS s
INNER JOIN #Users AS u
ON u.Name = ut.[User]
INNER JOIN #Tags AS t
ON t.TagName = s.Value;
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句