从动态字符串源中提取特定单词

时间:2016-11-04 02:49:09

标签: sql sql-server tsql split

你好,虽然我多年来一直在使用这个网站搜索答案,但我对Stack溢出很新。所以我有这个问题从一个非常长的字符串中提取各种和具体的细节。问题是,字符串不是静态的,没有固定的索引,所以我不能使用子字符串函数。字符串输出的示例是这样的。



    #include stdio.h
    #include string.h
    void main()
    {
    //by Admiral Smith Nov 3. 2016
    char time[80];
    int len;
    char *correct;
    scanf("%s", &time);
    correct = (char *)malloc(strlen(time));
    if (!correct)
    {
        printf("\nmemory error");
        return;
    }
    memcpy(correct,&time,strlen(time)-1);
    correct[strlen(time)]='/0';
    printf("%s", correct);
    free(correct);
    }

如您所见,字符串的索引会相应调整,因此我不能依赖固定的子字符串函数。

我对SQL很新,并希望您就如何处理这个问题提出建议。

到目前为止,我尝试的方法只是子串。

更新:

抱歉,我忘了提到我没有提取任何字符或字符串的数据。我正在从这个字符串中提取一个确切的部分。例如,

Sample 1:
1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0   GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400

Sample 2:
1 AJ 2552 O 10/8/2016 0:0:0 6 PSI KTL 0   GK 2 10/28/2016 7:0:0 9/28/2016 8:5:0 O20YEARS 32.2400

我需要提取第一个日期,即“9/28/2016”和“PSI KTL”

从技术上讲,我需要从字符串中提取某个第n个单词。

现在,我正在尝试将空格用作分隔符,并将每个单词分配到临时表中,但它似乎现在不起作用。

谢谢!

3 个答案:

答案 0 :(得分:0)

试试这个:

CREATE FUNCTION GetWordBasedOnIndex(@text varchar(max),@index int)
RETURNS varchar(50)
AS
BEGIN
    DECLARE @RET VARCHAR(50),@counter int
    SET @text = LTRIM(RTRIM(@text))
    SET @counter = 1
    IF @counter < @index
    BEGIN
            SET @text = LTRIM(RTRIM(SUBSTRING(@text, CHARINDEX(' ',@text,1), LEN(@text) - CHARINDEX(' ',@text,1)+1)))
            SET @text = dbo.GetWordBasedOnIndex(@text,@index-1)
    END
    IF CHARINDEX(' ',@text,1)=0 SET  @RET = @text
    ELSE SET  @RET = SUBSTRING(@text,@counter,CHARINDEX(' ',@text,1))
    RETURN @RET
END

declare @string nvarchar(max)
set @string = '1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0 GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400';
SELECT DBO.GetWordBasedOnIndex(@string, 5)

如果从表中传递并根据索引获取单词:

declare @string nvarchar(max)
set @string = '1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0 GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400';
SELECT [dbo].[GetWordBasedOnIndex](@string, 5)


CREATE table #temp (msg nvarchar(max))
INSERT INTO #temp VALUES(@string)
SELECT [dbo].[GetWordBasedOnIndex](msg, 5) as test from #temp

drop table #temp

答案 1 :(得分:0)

请试试这个:

DECLARE @s varchar(8000)
DECLARE @s2 varchar(8000)


set @s = '1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0   GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400';

SET @s2 =SUBSTRING(@s, CHARINDEX('PSI KTL', @s), 8000)

select SUBSTRing(@s2, PATINDEX('%__/__/____%', @s2), 10)

<强>更新

如果您希望使用空格作为分隔符来解析字符串,则可以将SQL 2016的String_Split或类似的UDF函数用于其他版本:

DECLARE @s varchar(max)

set @s = '1 AJ 2552 O 10/8/2016 0:0:0 6 PSI KTL 0   GK   2 10/28/2016 7:0:0 9/28/2016 8:5:0 O20YEARS 32.2400';
SET @s = replace(@s, '  ', ' '); -- Here, you can replace other white spaces by single space.

WITH cte 
AS (
        SELECT  *,
                ROW_NUMBER() Over(ORDER BY (SELECT null)) as RN
        from string_split(@s, ' ')
    )
        SELECT * FROM cte 
         WHERE RN = 15

答案 2 :(得分:0)

另一个简单的解决方案,如果您使用 SQL Server 2016

1)使用STRING_SPLIT函数,使用指定的分隔符拆分字符表达式。

3)使用ISDATE功能

检测日期值

2)最后使用Top 1来检索第一行。

如下: -

SELECT TOP 1 * 
FROM STRING_SPLIT ('1 AJ 552 O 9/28/2016 0:0:0 6 PSI KTL 0   GK 2 9/28/2016 7:20:0 9/28/2016 8:35:0 O20YEARS 32.2400
', ' ') 
WHERE ISDATE(value) = 1 

<强>结果:

value
9/28/2016