我的数据库中有一个存储数据的列:
Description - (Width 1 Height 1)
我需要解析此字符串并将Width和Height插入2个新列。
我目前有这个查询:
SELECT CASE
WHEN Description LIKE '%Width %' THEN SUBSTRING(Description, CHARINDEX('Width ', Description) + 6, 1)
END AS Width,
CASE
WHEN Description LIKE '%Height %' THEN SUBSTRING(Description, CHARINDEX('Height ', Description) + 7, 1)
END AS Height
FROM table
这个查询效果很好,但如果我有这样的条目,它只抓取第一个数字:
Description - (Width 25 Height 10)
我知道这是因为我正在使用' 1'作为我的SUBSTRING的长度,但我不知道如何使这项工作正常。
答案 0 :(得分:1)
SQL Server不会使解析字符串变得容易。
SELECT LEFT(v.wstr, CHARINDEX(' ', v.wstr + ' ') - 1) as width,
LEFT(v.hstr, CHARINDEX(' ', v.hstr + ' ') - 1) as width,
FROM table OUTER APPLY
(VALUES (STUFF(Description, 1, CHARINDEX('Width ', Description + 'Width ') + 6, ''),
STUFF(Description, 1, CHARINDEX('Height ', Description + 'Height ') + 7, ''),
)
) v(wstr, hstr);
注意:
NULL
(很容易将CASE
添加回来)。答案 1 :(得分:0)
如果您正在使用SQL 2016,则可以使用STRING_SPLIT并解析各个部分。
如果没有,那就更难了:
SUBSTRING
我在这里制作了一堆不同的变量来说明LEN(@testString)
是如何工作的。基本上,在宽度之后获取索引,直到你到达下一个空格 - 对高度做同样的事情,除了我们正在查看25
以结束它。
这将正确返回10
,LTRIM(RTRIM(Width))
的宽度和高度。只要您可以保证字符串所在的格式,这种方法就有效 - 如果此格式发生更改,它将无法正常工作。
理想情况下,这些值将存储在数据库的不同列中 - 然后您不必担心SQL拆分字符串。
编辑:
作为旁注,您(可能)最终希望Height
和{{1}}删除最终产生的子字符串中的任何空格。
答案 2 :(得分:0)
除了大小写(高度xxxxx - 宽度xxxxx)
之外,此查询可以适用于任何长度的高度,宽度DECLARE @Description AS TABLE (Description varchar(50))
INSERT INTO @Description
VALUES( 'Width 252 Height 1011'), ('Width 2 Height 22'),('Width 2144'), ('Height 2133')
SELECT CHARINDEX('Width', 'Width 25 Height 10')
;WITH temps AS
(
SELECT
CASE
WHEN CHARINDEX('Height', d.Description) > 1 THEN CHARINDEX('Height', d.Description)
ELSE 1
END AS IndexPosition,
d.Description
FROM @Description d
)
SELECT
t.Description,
CASE
WHEN t.IndexPosition = 1 AND t.Description LIKE '%Width%' THEN RTRIM(LTRIM(REPLACE(t.Description,'Width','' )))
WHEN t.IndexPosition = 1 AND t.Description LIKE '%Height%' THEN NULL
ELSE RTRIM(LTRIM(REPLACE(SUBSTRING(t.Description, 0, t.IndexPosition -1),'Width','' )))
END AS Width,
CASE
WHEN t.IndexPosition = 1 AND t.Description LIKE '%Height%' THEN RTRIM(LTRIM(REPLACE(t.Description,'Height','' )))
WHEN t.IndexPosition = 1 AND t.Description LIKE '%Width%' THEN NULL
ELSE RTRIM(LTRIM(REPLACE(SUBSTRING(t.Description, t.IndexPosition, LEN(t.Description)),'Height','' )))
END AS Height
FROM temps t