我在一个表上有一个文本字段,该字段试图在select语句中分解为两个单独的列。我发誓上次使用它对我有用,但是现在它抛出错误“无效的长度参数”。我在做什么错了?
从单个列中拆分数据,如下所示:
“公司-部门-区域-团队-主管”
分为两列:
主管|团队
这就是我曾经发誓要工作的东西,但是现在已经不复存在了,我无法弄清楚!
Reverse(Left(Reverse(table.column),CHARINDEX(' ', Reverse(table.column))-1)) AS 'SUPERVISOR'
,LTRIM(LEFT(Substring(table.column,18,150),CHARINDEX(' - ', Substring(table.column,18,150))-1)) AS 'TEAM'
答案 0 :(得分:2)
如果项目的已知数量或最大数量,请考虑使用一些XML。也许更容易阅读和维护。
此外,如果您只对团队和主管感兴趣,则可以消除Pos1,Pos2,Pos3。
示例
Declare @YourTable Table ([ID] varchar(50),[SomeCol] varchar(50))
Insert Into @YourTable Values
(1,'CORP - DIVISION - REGION - TEAM - SUPERVISOR')
Select A.ID
,B.*
From @YourTable A
Cross Apply (
Select Pos1 = ltrim(rtrim(xDim.value('/x[1]','varchar(100)')))
,Pos2 = ltrim(rtrim(xDim.value('/x[2]','varchar(100)')))
,Pos3 = ltrim(rtrim(xDim.value('/x[3]','varchar(100)')))
,Pos4 = ltrim(rtrim(xDim.value('/x[4]','varchar(100)')))
,Pos5 = ltrim(rtrim(xDim.value('/x[5]','varchar(100)')))
,Pos6 = ltrim(rtrim(xDim.value('/x[6]','varchar(100)')))
,Pos7 = ltrim(rtrim(xDim.value('/x[7]','varchar(100)')))
,Pos8 = ltrim(rtrim(xDim.value('/x[8]','varchar(100)')))
,Pos9 = ltrim(rtrim(xDim.value('/x[9]','varchar(100)')))
From (Select Cast('<x>' + replace(SomeCol,'-','</x><x>')+'</x>' as xml) as xDim) as A
) B
返回
ID Pos1 Pos2 Pos3 Pos4 Pos5 Pos6 Pos7 Pos8 Pos9
1 CORP DIVISION REGION TEAM SUPERVISOR NULL NULL NULL NULL
编辑
如果您有非XML安全字符(<,>,...),请使用
...
From ( values (cast('<x>' + replace((Select replace(SomeCol,'-','§§Split§§') as [*] For XML Path('')),'§§Split§§','</x><x>')+'</x>' as xml))) A(xDim)
...
答案 1 :(得分:0)
在SQL Server 2016中,您可以使用 STRING_SPLIT()来实现。
STRING_SPLIT()可以通过拆分这些数据来帮助规范化数据 多值列。
我还使用了TRIM()函数(随SQL Server 2017引入)以删除空格,CTE,ROW_NUMBER()和PIVOT。
脚本下方:
—-1 Create a test table
CREATE TABLE #TestTable
(
TestColumn varchar(100)
)
—-2 Inserting your string into table
INSERT INTO #TestTable
VALUES ('0 - CORP - DIVISION - REGION - TEAM - SUPERVISOR')
--3 Final query
;WITH CTE_Table AS (
SELECT
TestColumn = TRIM(TestColumn)
FROM
#TestTable
)
,CTE_Table2 AS (
SELECT
S.Value
FROM
CTE_Table
CROSS APPLY STRING_SPLIT([TestColumn],'-') AS S
)
,CTE_FinalTable AS (
SELECT TOP 5
Value
,ROW_NUMBER() OVER (ORDER BY Value) AS RowNumber
FROM
CTE_Table2
ORDER BY
Value
)
SELECT
[1],[2],[3],[4],[5]
FROM
CTE_FinalTable
PIVOT
(MAX([value])
The FOR [RowNumber] IN ([1],[2],[3],[4],[5])
) AS P