返回以列中的字符开头的所有单词

时间:2017-12-11 19:15:35

标签: sql sql-server tsql sql-server-2014

我有一个VARCHAR列,其数据如下:

abc = :abc and this = :that

我需要一个查询来查找所有特殊的"单词"以此列数据中的冒号开头。我真的不需要任何其他数据(ID或其他),重复也没关系。如果需要,我可以在以后删除Excel中的重复项。所以如果这是唯一的一行,我喜欢这样的输出:

SpecialWords
:abc
:that

我认为它需要CHARINDEX或类似的东西。但由于专栏中可能有多个特殊词,我无法找到第一个:并删除其余部分。

非常感谢任何帮助!提前谢谢!

4 个答案:

答案 0 :(得分:2)

您必须根据空格拆分此值并仅返回以冒号:开头的字段,我提供了2个解决方案,以根据您需要的结果类型实现此目的(表或单个)值)

表值函数

您可以创建一个电视功能,将此列拆分为一个表格:

CREATE FUNCTION [dbo].[GETVALUES] 
    (   
    @DelimitedString    varchar(8000)
    )
RETURNS @tblArray TABLE
    (
    ElementID   int IDENTITY(1,1),  -- Array index
    Element     varchar(1000)               -- Array element contents
    )
AS
BEGIN

    -- Local Variable Declarations
    -- ---------------------------
    DECLARE @Index      smallint,
                    @Start      smallint,
                    @DelSize    smallint

    SET @DelSize = 1

    -- Loop through source string and add elements to destination table array
    -- ----------------------------------------------------------------------
    WHILE LEN(@DelimitedString) > 0
    BEGIN

        SET @Index = CHARINDEX(' ', @DelimitedString)

        IF @Index = 0
            BEGIN

            IF ((LTRIM(RTRIM(@DelimitedString))) LIKE ':%')
                INSERT INTO
                    @tblArray 
                    (Element)
                VALUES
                    (LTRIM(RTRIM(@DelimitedString)))

                BREAK
            END
        ELSE
            BEGIN

             IF (LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1)))) LIKE ':%'
                INSERT INTO
                    @tblArray 
                    (Element)
                VALUES
                    (LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1))))

                SET @Start = @Index + @DelSize
                SET @DelimitedString = SUBSTRING(@DelimitedString, @Start , LEN(@DelimitedString) - @Start + 1)

            END
    END

    RETURN
END

你可以像下面那样使用它:

DECLARE @SQLStr varchar(100)
SELECT @SQLStr = 'abc = :abc and this = :that and xyz = :asd'

SELECT
    *
FROM
 dbo.GETVALUES(@SQLStr)

结果:

enter image description here

标量值函数

如果您需要返回一个值(不是表格),那么您可以使用此函数返回由分隔的所有值(换行符+ carridge返回CHAR(13) + CHAR(10)

CREATE FUNCTION dbo.GetValues2
(
    @DelimitedString    varchar(8000)
)
RETURNS varchar(8000)
AS
BEGIN

       DECLARE @Index      smallint,
                    @Start      smallint,
                    @DelSize    smallint,
                    @Result varchar(8000)

    SET @DelSize = 1
    SET @Result = ''

    WHILE LEN(@DelimitedString) > 0
    BEGIN

        SET @Index = CHARINDEX(' ', @DelimitedString)

        IF @Index = 0
            BEGIN

            if (LTRIM(RTRIM(@DelimitedString))) LIKE ':%'
           SET @Result = @Result + char(13) + char(10) +  (LTRIM(RTRIM(@DelimitedString)))

                BREAK
            END
        ELSE
            BEGIN

             IF (LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1)))) LIKE ':%'

                    SET @Result = @Result + char(13) + char(10) + (LTRIM(RTRIM(SUBSTRING(@DelimitedString, 1,@Index - 1))))

                SET @Start = @Index + @DelSize
                SET @DelimitedString = SUBSTRING(@DelimitedString, @Start , LEN(@DelimitedString) - @Start + 1)

            END
    END


    return @Result
END
GO

您可以将其用作以下

DECLARE @SQLStr varchar(100)
SELECT @SQLStr = 'abc = :abc and this = :that and xyz = :asd'

SELECT dbo.GetValues2(@SQLStr)

结果

enter image description here

表格结果换行中的

不可见,只需将数据复制到编辑器,它就会出现如图所示

<强>参考

答案 1 :(得分:0)

一种方法是编写专门的SPLIT函数。我建议从互联网上获取TSQL分割功能,看看你是否可以根据需要调整代码。

从头开始,您可以使用CHARINDEX编写一个循环遍历列值的函数,直到找不到:个字符为止。

答案 2 :(得分:0)

如何使用charindex

rextester示例:

create table mytable (testcolumn varchar(20))
insert into mytable values ('this = :that'),('yes'), (':no'), ('abc = :abc')


select right(testcolumn, charindex(':', reverse(testcolumn)) - 1) from mytable
where testcolumn like '%:%'

<强>参考

SQL Select everything after character

<强>更新

解决萨米的问题:

没有看到两个单词可能在一个冒号中,这个怎么样?

select replace(substring(testcolumn, charindex(':', testcolumn), len(testcolumn)), ':', '')

再次更新

我知道,实际的陈述是this = :that and that = :this

答案 3 :(得分:0)

如果性能很重要,那么您希望使用内联表值函数来拆分字符串并提取所需内容。您可以使用delimitedSplit8KdelimitedSplit8K_lead

declare @string varchar(8000) = 'abc = :abc and this = :that';

select item 
from dbo.DelimitedSplit8K(@string, ' ')
where item like ':%';

<强>返回:

item
------
:abc
:that

为了获得比我上面发布的更好的性能,您可以使用ngrams8k,如下所示:

declare @string varchar(8000) = 'abc = :abc and this = :that';

select position, item = 
  substring(@string, position,
    isnull(nullif(charindex(' ',@string,position+1),0),8000)-position)
from dbo.ngrams8k(@string, 1)
where token = ':';

这甚至可以为您提供所搜索项目的位置:

position   item
---------- -------
7          :abc
23         :that