我在SQL Server 2008 R2中有以下查询:
SELECT
Item.item,
(CASE
WHEN item.item LIKE 'RC-%' THEN 'Rectangle'
WHEN item.item LIKE 'T-%' THEN 'PIPE'
WHEN item.item LIKE 'B-%' THEN 'BAR'
END) as PROD_TYPE
FROM
item
WHERE
item.item LIKE 'RC-%' OR
item.item LIKE 'T-%' OR
item.item LIKE 'B-%'
产生此数据集:
item PROD_TYPE
=========================
B-10.000-XM12 BAR
B-1045-10.000 BAR
B-1045-10.500 BAR
B-1045-12.000 BAR
我需要将item列分成3个单独的列,这样看起来像这样:
item PROD_TYPE col1 col2 col3
===================================================
B-10.000-XM12 BAR B 10.000 XM12
B-1045-10.000 BAR B 1045 10.000
B-1045-10.500 BAR B 1045 10.500
B-1045-12.000 BAR B 1045 12.000
我尝试了以下查询:
SELECT
Item.item,
SUBSTRING (Item.item, 1, CHARINDEX('-', Item.item) - 1) col1,
SUBSTRING (Item.item, CHARINDEX ('-', Item.item) + 1, LEN(Item.item)) col2,
REVERSE (PARSENAME(REPLACE(REVERSE(REPLACE(Item.item,'.','/')), '-', '.'), 3)) as col3,
(CASE
WHEN item.item LIKE 'RC-%' THEN 'Rectangle'
WHEN item.item LIKE 'T-%' THEN 'PIPE'
WHEN item.item LIKE 'B-%' THEN 'BAR'
END) as PROD_TYPE
FROM
item
WHERE
item.item LIKE 'RC-%' OR
item.item LIKE 'T-%' OR
item.item LIKE 'B-%'
,该查询返回以下结果:
item col1 col2 col3 PRO_TYPE
----------------------------------------------------
B-10.000-XM12 B 10.000-XM12 XM12 BAR
B-1045-10.000 B 1045-10.000 10/000 BAR
B-1045-10.500 B 1045-10.500 10/500 BAR
我只是想不通如何获取项目数据中最后一部分的破折号的下一个索引。
有想法吗?
答案 0 :(得分:1)
SQL Server具有糟糕的字符串拆分功能(提示,提示:数据库不是进行这些转换的最佳位置)。
我发现带有字符串函数的cross apply
是解决这些问题的最佳方法:
with items as (
select 'B-10.000-XM12' as item union all
select 'B-1045-10.000' as item union all
select 'B-1045-10.500' as item union all
select 'B-1045-12.000' as item
)
select *,
(CASE WHEN i.item LIKE 'RC-%' THEN 'Rectangle'
WHEN i.item LIKE 'T-%' THEN 'PIPE'
WHEN i.item LIKE 'B-%' THEN 'BAR'
END) as PROD_TYPE,
v1.col, v2.col, v2.rest
from items i cross apply
(values (left(i.item, charindex('-', i.item) - 1),
stuff(i.item, 1, charindex('-', i.item), ''))
) v1(col, rest) cross apply
(values (left(v1.rest, charindex('-', v1.rest) - 1),
stuff(v1.rest, 1, charindex('-', v1.rest), ''))
) v2(col, rest);
Here是db <>小提琴。
答案 1 :(得分:1)
另一个选择
Declare @YourTable Table ([item] varchar(50),[PROD_TYPE] varchar(50))
Insert Into @YourTable Values
('B-10.000-XM12','BAR')
,('B-1045-10.000','BAR')
,('B-1045-10.500','BAR')
,('B-1045-12.000','BAR')
Select A.*
,B.*
From @YourTable A
Cross Apply (
Select Pos1 = xDim.value('/x[1]','varchar(100)')
,Pos2 = xDim.value('/x[2]','varchar(100)')
,Pos3 = xDim.value('/x[3]','varchar(100)')
From ( values (cast('<x>' + replace([item],'-','</x><x>')+'</x>' as xml))) A(xDim)
) B
返回
item PROD_TYPE Pos1 Pos2 Pos3
B-10.000-XM12 BAR B 10.000 XM12
B-1045-10.000 BAR B 1045 10.000
B-1045-10.500 BAR B 1045 10.500
B-1045-12.000 BAR B 1045 12.000
答案 2 :(得分:0)
交叉应用使表达式嵌套看起来很整洁:
select Item.item,
prod_type = case
WHEN item.item like 'RC-%' THEN 'Rectangle'
WHEN item.item like 'T-%' THEN 'PIPE'
WHEN item.item like 'B-%' THEN 'BAR'
end,
col1 = left(item, h1.pos - 1),
col2 = substring(item, h1.pos + 1, h2.pos - h1.pos - 1),
col3 = right(item, len(item) - h2.pos)
from item
cross apply (select charindex('-', item)) h1(pos)
cross apply (select charindex('-', item, h1.pos + 1)) h2(pos)
where item.item like 'RC-%'
or item.item LIKE 'T-%'
or item.item LIKE 'B-%'
答案 3 :(得分:0)
其他答案中列出了多个选项-正如我之前评论的那样-此https://datamajor.net/mssqlsplitcolumn/
中列出了您的方案的详细说明已经发布了几个选项作为答案,并列出了剩下的选项-
create Table tabl ([item] varchar(50),[PROD_TYPE] varchar(50));
Insert Into tabl Values
('B-10.000-XM12','BAR')
,('B-1045-10.000','BAR')
,('B-1045-10.500','BAR')
,('B-1045-12.000','BAR');
方法1. String_Split
WITH C AS(
SELECT ITEM
,value
,ROW_NUMBER() OVER(PARTITION BY ITEM ORDER BY (SELECT NULL)) as rn
FROM tabl BO
CROSS APPLY STRING_SPLIT(ITEM, '-') AS BK
)
SELECT ITEM
,[1] AS COL1
,[2] AS COl2
,[3] AS COL3
FROM C
PIVOT(
MAX(VALUE)
FOR RN IN([1],[2],[3])
) as PVT ;
使用功能
CREATE FUNCTION dbo.GetColumnValue(
@String VARCHAR(MAX),
@Delimiter CHAR(1),
@Column INT = 1
)
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE @idx INT
DECLARE @slice VARChar(MAX)
SELECT @idx = 1
IF LEN(@String)<1 OR @String IS NULL
RETURN NULL
DECLARE @ColCnt INT
SET @ColCnt = 1
WHILE (@idx != 0)
BEGIN
SET @idx = CHARINDEX(@Delimiter,@String)
IF @idx!=0
BEGIN
IF (@ColCnt = @Column)
RETURN LEFT(@String,@idx - 1)
SET @ColCnt = @ColCnt + 1
END
SET @String = RIGHT(@String,LEN(@String) - @idx)
IF LEN(@String) = 0 BREAK
END
RETURN @String
END
;
SELECT
ITEM ,
dbo.GetColumnValue(ITEM, '-', 1) as PRODUCTID
,dbo.GetColumnValue(ITEM, '-', 2) as NAME
,dbo.GetColumnValue(ITEM, '-', 3) as PAGES
FROM TABL