Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
T-SQL在分隔符上拆分列_Sql_Sql Server_Tsql_Sql Server 2012 - Fatal编程技术网

T-SQL在分隔符上拆分列

T-SQL在分隔符上拆分列,sql,sql-server,tsql,sql-server-2012,Sql,Sql Server,Tsql,Sql Server 2012,我有一个包含三组数据的列,数据以正斜杠分隔,如下所示 AB/1234/10 列在每一行中的格式始终相同,有2个字符、一个斜杠、一些字符数、一个斜杠,然后还有2个字符。我需要把这一栏分成三栏。所以上面的例子变成了 Column1 Column2 Column3 AB 1234 10 我不太清楚该怎么办。我一直在使用selectsubstring,但这并不能满足我的需要 select SUBSTRING(MyColumn, 1, CHARINDEX('/', MyColumn,

我有一个包含三组数据的列,数据以正斜杠分隔,如下所示

AB/1234/10
列在每一行中的格式始终相同,有2个字符、一个斜杠、一些字符数、一个斜杠,然后还有2个字符。我需要把这一栏分成三栏。所以上面的例子变成了

Column1 Column2 Column3
AB      1234    10
我不太清楚该怎么办。我一直在使用
selectsubstring
,但这并不能满足我的需要

select SUBSTRING(MyColumn, 1, CHARINDEX('/', MyColumn, 1)-1) 
FROM MyTable
将返回
AB
,这很好。但我无法集中精力思考如何抓住中间和结尾部分。我以为

select SUBSTRING(MyColumn, 4, CHARINDEX('/', MyColumn, 4)) 
FROM MyTable
可以抓住中间部分,但它返回
1234/10


我希望我的问题是明确的,我将感谢任何建议指向正确的方向,谢谢你

您可以使用固定偏移量,因为您定义了字符串始终以两个字符开头,以两个字符结尾

DECLARE @str VARCHAR(100) = 'AB/1234/10'

SELECT LEFT(@str, CHARINDEX('/', @str) - 1) AS Column1
    , SUBSTRING(@str, CHARINDEX('/', @str) + 1, CHARINDEX('/', SUBSTRING(@str, CHARINDEX('/', @str) + 1, LEN(@str))) - 1) AS Column2
    , RIGHT(@str, CHARINDEX('/', REVERSE(@str)) - 1) AS Column3
下面是一个完整的工作示例:

DECLARE @tmp TABLE (
  Merged nvarchar(max)
)

INSERT INTO @tmp SELECT N'AB/1234/10'
INSERT INTO @tmp SELECT N'AB/ANYNUMBEROF-CHARACTERS/10'

SELECT
  LEFT(Merged,2) AS Column1,
  SUBSTRING(Merged,4,LEN(Merged)-6) AS Column2,
  RIGHT(Merged,2) AS Column3
FROM @tmp
我们减去字符串的长度减去一个常数(6=左两个字符,右两个字符,两个斜线),从中间提取可变长度部分

结果:

Column1 Column2 Column3 AB 1234 10 AB ANYNUMBEROF-CHARACTERS 10 第1栏第2栏第3栏 AB 1234 10 AB任意字符数10
您可以使用固定偏移量,因为您定义了字符串始终以两个字符开头,以两个字符结尾

DECLARE @str VARCHAR(100) = 'AB/1234/10'

SELECT LEFT(@str, CHARINDEX('/', @str) - 1) AS Column1
    , SUBSTRING(@str, CHARINDEX('/', @str) + 1, CHARINDEX('/', SUBSTRING(@str, CHARINDEX('/', @str) + 1, LEN(@str))) - 1) AS Column2
    , RIGHT(@str, CHARINDEX('/', REVERSE(@str)) - 1) AS Column3
下面是一个完整的工作示例:

DECLARE @tmp TABLE (
  Merged nvarchar(max)
)

INSERT INTO @tmp SELECT N'AB/1234/10'
INSERT INTO @tmp SELECT N'AB/ANYNUMBEROF-CHARACTERS/10'

SELECT
  LEFT(Merged,2) AS Column1,
  SUBSTRING(Merged,4,LEN(Merged)-6) AS Column2,
  RIGHT(Merged,2) AS Column3
FROM @tmp
我们减去字符串的长度减去一个常数(6=左两个字符,右两个字符,两个斜线),从中间提取可变长度部分

结果:

Column1 Column2 Column3 AB 1234 10 AB ANYNUMBEROF-CHARACTERS 10 第1栏第2栏第3栏 AB 1234 10 AB任意字符数10
一种方法是使用
PARSENAME

SELECT PARSENAME(REPLACE('AB/1234/10','/','.'), 3) Col1,
       PARSENAME(REPLACE('AB/1234/10','/','.'), 2) Col2,
       PARSENAME(REPLACE('AB/1234/10','/','.'), 1) Col3
这将用
替换
,并用
PARSENAME
拉出字符串的每个部分


好处是它可以处理任何位置的任意长度的字符。限制是
PARSENAME
最多只能处理4个位置(在本例中,您使用的是3个),如果字符串中已经存在句点
,则将失败。

一种方法是使用
PARSENAME

SELECT PARSENAME(REPLACE('AB/1234/10','/','.'), 3) Col1,
       PARSENAME(REPLACE('AB/1234/10','/','.'), 2) Col2,
       PARSENAME(REPLACE('AB/1234/10','/','.'), 1) Col3
这将用
替换
,并用
PARSENAME
拉出字符串的每个部分


好处是它可以处理任何位置的任意长度的字符。限制是
PARSENAME
最多只能处理4个位置(在本例中,您使用的是3个),如果字符串中已经存在句点
,则将失败。

试试这个。这应该适用于任意数量的字符

DECLARE @str VARCHAR(100) = 'AB/1234/10'

SELECT LEFT(@str, CHARINDEX('/', @str) - 1) AS Column1
    , SUBSTRING(@str, CHARINDEX('/', @str) + 1, CHARINDEX('/', SUBSTRING(@str, CHARINDEX('/', @str) + 1, LEN(@str))) - 1) AS Column2
    , RIGHT(@str, CHARINDEX('/', REVERSE(@str)) - 1) AS Column3

试试这个。这应该适用于任意数量的字符

DECLARE @str VARCHAR(100) = 'AB/1234/10'

SELECT LEFT(@str, CHARINDEX('/', @str) - 1) AS Column1
    , SUBSTRING(@str, CHARINDEX('/', @str) + 1, CHARINDEX('/', SUBSTRING(@str, CHARINDEX('/', @str) + 1, LEN(@str))) - 1) AS Column2
    , RIGHT(@str, CHARINDEX('/', REVERSE(@str)) - 1) AS Column3

理想情况下,这项工作的一部分应该是永久性地分离这些数据。像这样存储多个元素违反1NF,处理起来非常痛苦。如果在建议的副本中使用类似的拆分器,则应避免使用可接受的答案,因为这是拆分字符串的可怕方式。相反,向下滚动到Aaron Bertrand的答案。这对性能更好。理想情况下,此练习的一部分应该是永久分离此数据。像这样存储多个元素违反1NF,处理起来非常痛苦。如果在建议的副本中使用类似的拆分器,则应避免使用可接受的答案,因为这是拆分字符串的可怕方式。相反,向下滚动到Aaron Bertrand的答案。它的性能要好得多。我非常喜欢这个技巧,但是如果任何源字符串包含一个点,它都会失败。处理句点的一个简单方法是先添加一个替换来替换一个句点。有点像^。当然,对于这个简单的字符串,你必须把它换回来,哪种类型的字符串开始有点过头了。不幸的是,我的案例中的任何或所有字符串都可能包含一个
,因此,虽然这个答案很好,但它不适用于我的案例。无论如何,谢谢。我非常喜欢这个技巧,但是如果任何源字符串包含一个点,它都会失败。处理句点的一个简单方法是先添加一个替换以替换掉一个句点。有点像^。当然,对于这个简单的字符串,你必须把它换回来,哪种类型的字符串开始有点过头了。不幸的是,我的案例中的任何或所有字符串都可能包含一个
,因此,虽然这个答案很好,但它不适用于我的案例。无论如何,谢谢。如果我能将多个答案标记为正确,我也会将这一个标记为正确,它本质上与我标记为正确的答案相同,但我真的很欣赏它的健壮性。它更适用于一般用途。谢谢。如果我能将多个答案标记为正确,我也会将这一个标记为正确,它本质上与我标记为正确的答案相同,但我真的很欣赏它的健壮性。它更适用于一般用途。非常感谢。