计算列中的单词
Counting words in column
我必须得到标签的计数
<name></name>
列中。
<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>
在此示例数据中,查询应 return 3.
使用 XPath 可以轻松实现逻辑。
您的场景的 XPath 示例:count(/users/name)
结果:3
动态sql解决方案:
DECLARE @Table TABLE (Names NVARCHAR(1100))
INSERT INTO @Table VALUES
('<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>'),
('<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>'),
('<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>')
DECLARE @Sql NVARCHAR(MAX)
SET @Sql = ''
SELECT
@Sql = @Sql +
REPLACE(
REPLACE(
REPLACE(
REPLACE(Names,'</name>',''' as Names UNION ALL ')
,'<name>','SELECT ''')
,'</users>','')
,'<users>','')+CHAR(10)
FROM @Table
SET @Sql = LEFT(@Sql,LEN(@Sql)-11)
SET @Sql = 'SELECT COUNT(Names) AS Names FROM (' + @Sql + ') as AllNames'
EXEC(@Sql)
如果您使用 xml 数据,请尝试此变体
DECLARE @XMLdata XML = N'<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>'
SELECT COUNT(*)
FROM @XMLdata.nodes('/users/name') col ( name )
当数据存储为字符串 (varchar) 时,此变体很有用
--create temp table for testing
IF OBJECT_ID('Tempdb..#Tags') IS NOT NULL
DROP TABLE #Tags
CREATE TABLE #Tags
(
SampleText VARCHAR(1000)
)
INSERT INTO #Tags
( SampleText )
VALUES ( '<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>' ),
( '<users><name>Somik</name><name>Pawel</name><name>Krzysiek</name></users>' ),
( '<users><name>Krolik</name><name>Pawel</name><name>Krzysiek</name></users>' ),
( '<users><name>Domik</name><name>Pawel</name><name>Krzysiek</name></users>' ),
( '<users><name>Zontik</name><name>Pawel</name><name>Krzysiek</name></users>' );
--------------------------------------------------------------------------------
-- recursive cte for split string
WITH cte
AS ( SELECT n = 1
UNION ALL
SELECT n + 1
FROM cte
WHERE n <= 1000
)
--------------------------------------------------------------------------------
-- final query
SELECT COUNT(*) AS Cnt
FROM cte
JOIN #Tags AS T ON n <= LEN(T.SampleText)
WHERE SUBSTRING(T.SampleText, n, 7) = '</name>'
OPTION ( MAXRECURSION 1000 )
我必须得到标签的计数
<name></name>
列中。
<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>
在此示例数据中,查询应 return 3.
使用 XPath 可以轻松实现逻辑。
您的场景的 XPath 示例:count(/users/name)
结果:3
动态sql解决方案:
DECLARE @Table TABLE (Names NVARCHAR(1100))
INSERT INTO @Table VALUES
('<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>'),
('<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>'),
('<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>')
DECLARE @Sql NVARCHAR(MAX)
SET @Sql = ''
SELECT
@Sql = @Sql +
REPLACE(
REPLACE(
REPLACE(
REPLACE(Names,'</name>',''' as Names UNION ALL ')
,'<name>','SELECT ''')
,'</users>','')
,'<users>','')+CHAR(10)
FROM @Table
SET @Sql = LEFT(@Sql,LEN(@Sql)-11)
SET @Sql = 'SELECT COUNT(Names) AS Names FROM (' + @Sql + ') as AllNames'
EXEC(@Sql)
如果您使用 xml 数据,请尝试此变体
DECLARE @XMLdata XML = N'<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>'
SELECT COUNT(*)
FROM @XMLdata.nodes('/users/name') col ( name )
当数据存储为字符串 (varchar) 时,此变体很有用
--create temp table for testing
IF OBJECT_ID('Tempdb..#Tags') IS NOT NULL
DROP TABLE #Tags
CREATE TABLE #Tags
(
SampleText VARCHAR(1000)
)
INSERT INTO #Tags
( SampleText )
VALUES ( '<users><name>Tomek</name><name>Pawel</name><name>Krzysiek</name></users>' ),
( '<users><name>Somik</name><name>Pawel</name><name>Krzysiek</name></users>' ),
( '<users><name>Krolik</name><name>Pawel</name><name>Krzysiek</name></users>' ),
( '<users><name>Domik</name><name>Pawel</name><name>Krzysiek</name></users>' ),
( '<users><name>Zontik</name><name>Pawel</name><name>Krzysiek</name></users>' );
--------------------------------------------------------------------------------
-- recursive cte for split string
WITH cte
AS ( SELECT n = 1
UNION ALL
SELECT n + 1
FROM cte
WHERE n <= 1000
)
--------------------------------------------------------------------------------
-- final query
SELECT COUNT(*) AS Cnt
FROM cte
JOIN #Tags AS T ON n <= LEN(T.SampleText)
WHERE SUBSTRING(T.SampleText, n, 7) = '</name>'
OPTION ( MAXRECURSION 1000 )