计算列中的单词

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

Test Here

动态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 )