Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/25.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
Sql server 拆分字符串';1/10/2/20/3/30/4/40';分为两列,检查正文以了解更多详细信息_Sql Server_Split - Fatal编程技术网

Sql server 拆分字符串';1/10/2/20/3/30/4/40';分为两列,检查正文以了解更多详细信息

Sql server 拆分字符串';1/10/2/20/3/30/4/40';分为两列,检查正文以了解更多详细信息,sql-server,split,Sql Server,Split,我尝试了以下代码: string = '1/10/2/20/3/30/4/40' output = col1 | col2 1 | 10 2 | 20 3 | 30 4 | 40 这是输出,但更像是硬编码。我尝试创建临时表。将一位数字添加到一个临时表中,将非一位数字添加到另一个临时表中。并将两个表的值放入另一个临时表中 代码: 注意:@系列是我传递的字符串 DE

我尝试了以下代码:

string = '1/10/2/20/3/30/4/40'
output = col1  |   col2
           1   |    10
           2   |    20
           3   |    30
           4   |    40

这是输出,但更像是硬编码。

我尝试创建临时表。将一位数字添加到一个临时表中,将非一位数字添加到另一个临时表中。并将两个表的值放入另一个临时表中

代码:
注意:@系列是我传递的字符串

DECLARE @TEXT VARCHAR(60) = '1/10/2/20/3/30/4/40', @POSITION INT=1
CREATE TABLE #TEMP(VAL1 INT,VAL2 INT)
WHILE (LEN(@TEXT) >= @POSITION)
BEGIN
  INSERT INTO #TEMP VALUES(SUBSTRING(@TEXT,@POSITION,1),SUBSTRING(@TEXT,@POSITION+2,2))
  SET @POSITION = @POSITION+5
END

SELECT * FROM #TEMP

下次请说明您的SQL Server版本

以下解决方案适用于几乎任何版本,如果您在v2016+上,可能会有更好的方法。试试这个:

select value into #value from string_split(@series,'/')

create table #position(var int identity(1,1),var1 int)

insert into #position(var1)    
select value from #value    where value like '_'

create table #position2(var int,var2 int)

insert into #position2(var2)   
select value from #value where value not like '_'

create table #final(var1 int,var2 int)

insert into #final(var1,var2)    
select p1.var1,p2.var2 from #position p1                
      join #position2 p2 on p1.var=p2.var

select * from #final
简而言之:

  • cte将把CSV列表转换为JSON数组
  • 我们使用
    OPENJSON
    来读取这个数组
  • 键是元素位置。与
    %2
    (模运算符)一起,我们得到一个计算的、交替的列名
  • 最后,我们可以使用
    PIVOT
    将您的值分散到
    Col1
    Col2
  • A.[key]/2
    将使用带整数除法的技巧为每个组创建一个数字(否则您将只看到最后一行)

Chirag,这应该是你问题的一部分。。。使用问题下方的“编辑”选项更改此选项。一般来说:一个好的问题包括样本数据、预期的ouptut和您自己的尝试以及一些解释。所有这些最好作为(一个自运行和独立的示例)使用。只要再次查看您的代码,我就会看到
string\u split()
。这是非常危险的。。。此函数不保证按预期的排序顺序返回元素…好的,这是一个有用的函数。我在SQL中学到了一些新东西。我只是怀疑使用交叉连接是不好的做法,对吗?@ChiragSheth,不
交叉连接
不是“不好的做法”。它是一个简单的each with each join(笛卡尔积)。在这种情况下,我们保证在cte
铸造中有一个衬里。
交叉连接
是将理货集绑定到此单行的最简单方法,以便根据需要重复。
DECLARE @TEXT VARCHAR(60) = '1/10/2/20/3/30/4/40';

WITH Casted(ToXml) AS
(
    SELECT CAST('<x>' + REPLACE(@TEXT,'/','</x><x>') + '</x>' AS XML)
)
,TallyOddNumbers(OddNumber) AS
(   
    SELECT TOP((SELECT ToXml.value('count(/x)','int')/2 FROM Casted)) (ROW_NUMBER() OVER(ORDER BY (SELECT NULL)))*2-1 FROM master..spt_values
)
SELECT ToXml.value('/x[sql:column("OddNumber")][1]','int') AS Col1
      ,ToXml.value('/x[sql:column("OddNumber")+1][1]','int') AS Col1
FROM Casted
CROSS JOIN TallyOddNumbers;
DECLARE @TEXT VARCHAR(60) = '1/10/2/20/3/30/4/40';


WITH ToJson(j) AS(SELECT CONCAT('[',REPLACE(@TEXT,'/',','),']'))
SELECT p.Col1
      ,p.Col2
FROM
(
    SELECT A.[key] /2 AS GroupIndex
          ,CONCAT('Col',A.[key]%2 +1) AS ColumnName
          ,A.[value] AS TheValue 
    FROM ToJson
    CROSS APPLY OPENJSON(j) A
) t
PIVOT
(
    MAX(TheValue) FOR ColumnName IN(Col1,Col2)
) p;