如何在单独的列中将冒号前后的单词拆分为sql中的行

时间:2019-05-30 15:39:12

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

我在表中有一列[LongText],其行值是所有属性及其值的合并。以下是示例。 如预期结果所示,我们可以将单词前后的冒号分为两列吗?在sql 2014中需要它

Longtext

TYPE: SOLID WEDGE 1,SOLID WEDGE 2,  VALVE SIZE: 1 IN,  PRESSURE RATING: 800 LB,  CONNECTION TYPE: SOCKET WELD,  BONNET STYLE: BOLTED

预期输出分为两列属性和值:

Attribute        | Value
----------------------------------------------
TYPE             | SOLID WEDGE 1,SOLID WEDGE 2
VALVE SIZE       | 1 IN
PRESSURE RATING  | 800 LB
CONNECTION TYPE  | SOCKET WELD
BONNET STYLE     | BOLTED

2 个答案:

答案 0 :(得分:0)

从STRING_SPLIT()开始,类似于:

DECLARE @string varchar(max) = 'TYPE: SOLID WEDGE 1,SOLID WEDGE 2,  VALVE SIZE: 1 IN,  PRESSURE RATING: 800 LB .....';
DECLARE @output varchar(max) = '';
DECLARE @v varchar(max) = (SELECT TOP(1) value from string_split(@string,' '));
WHILE @v <> ''
BEGIN
    select @v;
    SET @string = (SELECT ltrim(substring(@string,LEN(@v)+1,1024)));
    select @string;
    SET @v = (SELECT TOP(1) value from string_split(@string,' '));
END

给出: output of above script

如@Tim所说,上述方法不能保证顺序正确。

所以,第二次尝试:

DECLARE @string varchar(max) = 'TYPE: SOLID WEDGE 1,SOLID WEDGE 2,  VALVE SIZE: 1 IN,  PRESSURE RATING: 800 LB,  CONNECTION TYPE: SOCKET WELD,  BONNET STYLE: BOLTED';
SELECT * FROM string_split(REPLACE(@string,'  ','#'),'#');

这希望(=“不检查”)原始字符串中没有'#'字符。

答案 1 :(得分:0)

看看这是否有帮助。另外,请告诉我您是否要解释代码。

IF EXISTS(SELECT 1 FROM SYS.OBJECTS WHERE NAME = 'fn_GetAttributeAndValueFromLongText' AND TYPE = 'TF')
BEGIN
    DROP FUNCTION dbo.fn_GetAttributeAndValueFromLongText
END
GO

CREATE FUNCTION dbo.fn_GetAttributeAndValueFromLongText ( @String_LongText VARCHAR(MAX) )
RETURNS @TBL_Attribute_Value TABLE 
(
    Attribute VARCHAR(MAX)
  , Value VARCHAR(MAX)
)
AS
BEGIN

    DECLARE @ATTR_VALUE_DELIMITER AS VARCHAR(MAX) = ':'

    WHILE (RTRIM(LTRIM(LEN(@String_LongText))) != 0)
    BEGIN
        DECLARE @String_ATTR VARCHAR(MAX)='', @String_VALUE VARCHAR(MAX)= ''

        SELECT @String_LongText = RTRIM(LTRIM(@String_LongText))

        SELECT @String_ATTR = SUBSTRING(@String_LongText, 1,CHARINDEX(':',@String_LongText)-1)
        SELECT @String_LongText = RIGHT(@String_LongText, LEN(@String_LongText)-(LEN(@String_ATTR)+1))

        IF @String_LongText LIKE '%'+@ATTR_VALUE_DELIMITER+'%'
        BEGIN
            SELECT @String_VALUE = LEFT(SUBSTRING(@String_LongText, 1, CHARINDEX(':', @String_LongText)-1), LEN(SUBSTRING(@String_LongText, 1, CHARINDEX(':', @String_LongText)-1)) - CHARINDEX(',', REVERSE(SUBSTRING(@String_LongText, 1, CHARINDEX(':', @String_LongText)-1))))
            SELECT @String_LongText = RIGHT(@String_LongText, LEN(@String_LongText)-(LEN(@String_VALUE)+1))
        END
        ELSE
        BEGIN
            SELECT @String_VALUE = @String_LongText
            SELECT @String_LongText = REPLACE(@String_LongText, @String_VALUE, '')
        END

        INSERT INTO @TBL_Attribute_Value ([Attribute], [Value])
        VALUES(RTRIM(LTRIM(@String_ATTR)), RTRIM(LTRIM(@String_VALUE))) 
    END

    RETURN
END

GO 

SELECT * FROM dbo.fn_GetAttributeAndValueFromLongText('TYPE: SOLID WEDGE 1,SOLID WEDGE 2,  VALVE SIZE: 1 IN,  PRESSURE RATING: 800 LB,  CONNECTION TYPE: SOCKET WELD,  BONNET STYLE: BOLTED')