统计单个标签的数量 post - data explorer
Counting the number of tags in a single post - data explorer
我正在尝试编写一个查询来计算单个 post 下的标签数量。不知何故,我无法全神贯注地将标签分成一行并计算这些标签。
Other posts建议创建一个函数来拆分标签,但不能创建数据交换函数。
这是我目前的查询,它只会给我帖子和标签中的 post。
SELECT p.Id, p.Title, p.Tags, t.TagName
FROM Posts as p
INNER JOIN Tags as t ON p.Id = t.Id
我猜你需要这样的东西
SELECT p.Id, p.Title, p.Tags, count(t.TagName)
FROM Posts as p
INNER JOIN Tags as t ON p.Id = t.Id
group by p.Id, p.Title, p.Tags
您可以使用 Tags
列计算标签数量:
SELECT Id, Title, Tags, LEN(Tags) - LEN(REPLACE(Tags, '<','')) AS tag_number
FROM Posts as p
WHERE Id = 2647
您可以使用 JOIN 将其作为
SELECT P.ID,
P.Title,
P.Tags,
COUNT(Tags) TagsCount
FROM Posts P INNER JOIN PostTags PT
ON P.Id = PT.PostId
WHERE P.ID = 53243136
GROUP BY P.ID,
P.Title,
P.Tags;
更新:
这里还有一个方法
SELECT P.ID,
P.Title,
P.Tags,
COUNT(TT.Value) - 1 TagsCount
FROM Posts P CROSS APPLY (SELECT Value FROM STRING_SPLIT(Tags, '>')) TT
WHERE P.ID = 53243136
GROUP BY P.ID,
P.Title,
P.Tags;
这接近于猜测,但我的魔法 crystal 球(和 Martin Smith)告诉我,您可能正在寻找这样的东西:
DECLARE @mokupPosts TABLE(ID INT IDENTITY, SomePost VARCHAR(250),Tags VARCHAR(250));
INSERT INTO @mokupPosts VALUES
('First post','<matlab><plot><ternary><ternplot>')
,('Second post','<powershell><java><python>')
,('Third post','<image><opencv><image-processing>');
--查询将 return 每个 Post
多行,每个标记分别。
SELECT p.*
,B.token.value('text()[1]','varchar(100)') Token
FROM @mokupPosts p
CROSS APPLY(SELECT CAST('<x>' + REPLACE(REPLACE(REPLACE(REPLACE(p.Tags,'><','||'),'<',''),'>',''),'||','</x><x>') + '</x>' AS XML)) A(Casted)
CROSS APPLY A.Casted.nodes('/x') B(token);
您可以轻松地 INNER JOIN
将其直接添加到令牌上的现有 table Tags
并执行分组 COUNT()
.
如果标签可能包含禁用字符(如 &, < and >
等),您可以使用额外的内部 SELECT FOR XML PATH('')
隐式转义它们:
SELECT p.*
,B.token.value('text()[1]','varchar(100)') Token
FROM @mokupPosts p
CROSS APPLY(SELECT CAST('<x>' + REPLACE((SELECT REPLACE(REPLACE(REPLACE(p.Tags,'><','||'),'<',''),'>','') AS [*] FOR XML PATH('')),'||','</x><x>') + '</x>' AS XML)) A(Casted)
CROSS APPLY A.Casted.nodes('/x') B(token);
更新:更简单的方法
注意:标签不得包含元素名称中禁止使用的字符,例如 &, < and >
(以及更多)!
此查询将 return 一个空元素列表 作为 xml 只需将结束 >
替换为 />
.然后查询将使用 /*
迭代所有这些,并通过 local-name(.)
:
return 他们的名字
SELECT p.*
,B.token.value('local-name(.)','varchar(100)')AS Token
FROM @mokupPosts p
CROSS APPLY(SELECT CAST(REPLACE(p.Tags,'>','/>') AS XML)) A(Casted)
CROSS APPLY A.Casted.nodes('/*') B(token)
结果同上...
更新 2:我刚试过这个 here
...并且有效:-)
我正在尝试编写一个查询来计算单个 post 下的标签数量。不知何故,我无法全神贯注地将标签分成一行并计算这些标签。
Other posts建议创建一个函数来拆分标签,但不能创建数据交换函数。
这是我目前的查询,它只会给我帖子和标签中的 post。
SELECT p.Id, p.Title, p.Tags, t.TagName
FROM Posts as p
INNER JOIN Tags as t ON p.Id = t.Id
我猜你需要这样的东西
SELECT p.Id, p.Title, p.Tags, count(t.TagName)
FROM Posts as p
INNER JOIN Tags as t ON p.Id = t.Id
group by p.Id, p.Title, p.Tags
您可以使用 Tags
列计算标签数量:
SELECT Id, Title, Tags, LEN(Tags) - LEN(REPLACE(Tags, '<','')) AS tag_number
FROM Posts as p
WHERE Id = 2647
您可以使用 JOIN 将其作为
SELECT P.ID,
P.Title,
P.Tags,
COUNT(Tags) TagsCount
FROM Posts P INNER JOIN PostTags PT
ON P.Id = PT.PostId
WHERE P.ID = 53243136
GROUP BY P.ID,
P.Title,
P.Tags;
更新:
这里还有一个方法
SELECT P.ID,
P.Title,
P.Tags,
COUNT(TT.Value) - 1 TagsCount
FROM Posts P CROSS APPLY (SELECT Value FROM STRING_SPLIT(Tags, '>')) TT
WHERE P.ID = 53243136
GROUP BY P.ID,
P.Title,
P.Tags;
这接近于猜测,但我的魔法 crystal 球(和 Martin Smith)告诉我,您可能正在寻找这样的东西:
DECLARE @mokupPosts TABLE(ID INT IDENTITY, SomePost VARCHAR(250),Tags VARCHAR(250));
INSERT INTO @mokupPosts VALUES
('First post','<matlab><plot><ternary><ternplot>')
,('Second post','<powershell><java><python>')
,('Third post','<image><opencv><image-processing>');
--查询将 return 每个 Post
多行,每个标记分别。
SELECT p.*
,B.token.value('text()[1]','varchar(100)') Token
FROM @mokupPosts p
CROSS APPLY(SELECT CAST('<x>' + REPLACE(REPLACE(REPLACE(REPLACE(p.Tags,'><','||'),'<',''),'>',''),'||','</x><x>') + '</x>' AS XML)) A(Casted)
CROSS APPLY A.Casted.nodes('/x') B(token);
您可以轻松地 INNER JOIN
将其直接添加到令牌上的现有 table Tags
并执行分组 COUNT()
.
如果标签可能包含禁用字符(如 &, < and >
等),您可以使用额外的内部 SELECT FOR XML PATH('')
隐式转义它们:
SELECT p.*
,B.token.value('text()[1]','varchar(100)') Token
FROM @mokupPosts p
CROSS APPLY(SELECT CAST('<x>' + REPLACE((SELECT REPLACE(REPLACE(REPLACE(p.Tags,'><','||'),'<',''),'>','') AS [*] FOR XML PATH('')),'||','</x><x>') + '</x>' AS XML)) A(Casted)
CROSS APPLY A.Casted.nodes('/x') B(token);
更新:更简单的方法
注意:标签不得包含元素名称中禁止使用的字符,例如 &, < and >
(以及更多)!
此查询将 return 一个空元素列表 作为 xml 只需将结束 >
替换为 />
.然后查询将使用 /*
迭代所有这些,并通过 local-name(.)
:
SELECT p.*
,B.token.value('local-name(.)','varchar(100)')AS Token
FROM @mokupPosts p
CROSS APPLY(SELECT CAST(REPLACE(p.Tags,'>','/>') AS XML)) A(Casted)
CROSS APPLY A.Casted.nodes('/*') B(token)
结果同上...
更新 2:我刚试过这个 here
...并且有效:-)