返回查询结果集中的列子字符串?

时间:2015-07-20 12:03:56

标签: sql-server tsql

假设我有一个名为模块的字符串列,其类型为nvarchar(max),其中包含由下划线分隔的多个字段的信息。但它也可以有一个随机格式,不用下划线分隔。

"Field1_Field2_Field3_Field4_Field5"
"Field1_Field2_Field3_Field4_Field5_Field6"
"Field1_Field2_Field3"
"RandomString"

我想构建一个T-SQL查询,该查询返回该列中的信息等。如果该列的实例具有随机格式,则完全以其原始格式返回。如果它采用上述第一种格式,则仅返回由下划线分隔的前4个字段。基本上是原始字符串的子字符串。

结果集:

"Field1_Field2_Field3_Field4"
"Field1_Field2_Field3_Field4"
"Field1_Field2_Field3"
"RandomString"

我将如何实现这一目标?我在想一个可以在CLR程序中实现的正则表达式,但我之前没有使用它们。

3 个答案:

答案 0 :(得分:2)

这可能会有所帮助。

  Declare @Input as varchar(50) = 'Field1_Field2_Field3_Field4_Field5'
  DEClare @Character as CHAR(1) = '_'
  DECLARE @StartIndex INT, @EndIndex INT


DECLARE @Output TABLE (ID int IDENTITY(1,1),
  Item NVARCHAR(1000)
)

SET @StartIndex = 1
IF SUBSTRING(@Input, LEN(@Input) - 1, LEN(@Input)) <> @Character
BEGIN
SET @Input = @Input + @Character
END

WHILE CHARINDEX(@Character, @Input) > 0
BEGIN
SET @EndIndex = CHARINDEX(@Character, @Input)

INSERT INTO @Output(Item)
SELECT SUBSTRING(@Input, @StartIndex, @EndIndex - 1)

SET @Input = SUBSTRING(@Input, @EndIndex + 1, LEN(@Input))
END

Declare @OutputString as NVARCHAR(1000) = ''

Select @OutputString = @OutputString +  Item + '_'
from @Output 
where ID < 5

Select LEFT(@OutputString, LEN(@OutputString) - 1) FinalOutput

答案 1 :(得分:1)

这个怎么样?这应该与您在示例数据中提供的方案一起使用。

SELECT CASE 
        WHEN charindex(removeelement, module) - 1 > 0
            THEN substring(module, 0, charindex(RemoveElement, module) - 1)
        ELSE module
        END MagicResult
FROM (
    SELECT SpecialChar
        ,module
        ,reverse(substring(reverse(module), 0, charindex(specialchar, reverse(module), 1))) 'RemoveElement'
    FROM (
        SELECT substring(module, patindex('%[^a-zA-Z0-9]%', module), 1) 'SpecialChar'
            ,module
        FROM test
        ) rs
    ) rs

另外,here is a SQLFiddle了解此代码如何处理您提供的示例数据。

答案 2 :(得分:0)

可以使用CLR程序完成,但我宁愿在前端进行。获取数据,然后使用string.Split(&#39; _&#39;)进行处理,例如类似于:

var field = "Field1_Field2_Field3_Field4_Field5";
var parts = field.Split('_');
if (parts.Length >= 4)
{
    parts = parts.Take(4).ToArray();
    Console.WriteLine(string.Join("_", parts));
}
else
{
    Console.WriteLine(field);
}