我目前在表格列中有char值,其格式为" IS - "然后是1到5个数字,一个可能的句号,带有2个数字或句点后面的字母。
例如,IS-1,IS-12,IS-123,IS-123.11,IS-123.a。
我需要拆分字符串,以便我只抓取数字部分,对字符串ASC进行排序,然后按照它们的方式将字符串重新组合在一起。
解释。我有以下一组值,IS-1170, IS-1171, IS-1172, IS-1173, IS-1174, IS-870.a, IS-871.a, IS-872.a.
正如您所看到的,因为IS-1出现在IS-8之前,它们是按数字顺序排序的。
知道从哪里开始?我在考虑使用CASE,但我不确定如何继续。
感谢。
答案 0 :(得分:2)
在ORDER BY
中执行字符串功能以仅删除该号码。这样的事情应该有效:
SELECT col
FROM table
ORDER BY CAST(CASE WHEN ISNUMERIC(SUBSTRING(col,4,20)) = 1
THEN SUBSTRING(col,4,20)
ELSE LEFT(SUBSTRING(col,4,20),CHARINDEX('.',SUBSTRING(col,4,20),0)-1)
END AS NUMERIC)
这将首先删除IS-
并检查字符串的其余部分是否为数字。如果是,它将保留小数位,否则将删除.
和以下字母字符。
这假设您在数字小数位的情况下的预期排序是:
IS-123.A
IS-123.1
IS-123.2
如果您不关心十进制/句点之后的内容,那么只需:
ORDER BY CAST(LEFT(SUBSTRING(col,4,20),CHARINDEX('.',SUBSTRING(col,4,20),0)-1) AS NUMERIC)
答案 1 :(得分:0)
如果我理解正确,这可能会对您有所帮助:
DECLARE @mockup TABLE(ID INT IDENTITY,YourExample VARCHAR(100));
INSERT INTO @mockup VALUES
('IS-1, IS-12, IS-123, IS-123.11, IS-123.a.')
,('IS-1170, IS-1171, IS-1172, IS-1173, IS-1174, IS-870.a, IS-871.a, IS-872.a');
WITH Splitted AS
(
SELECT *
,CAST('<x>' + REPLACE(m.YourExample,',','</x><x>') + '</x>' AS XML) AS SplitAtComma
FROM @mockup AS m
)
,NumberExtracted AS
(
SELECT s.ID
,part.value('text()[1]','nvarchar(max)') AS OnePart
,CAST('<y>' + REPLACE(REPLACE(part.value('text()[1]','nvarchar(max)'),'.','-'),'-','</y><y>') + '</y>' AS XML).value('/y[2]/text()[1]','int') AS TheNumber
FROM Splitted AS s
CROSS APPLY s.SplitAtComma.nodes('/x') AS A(part)
)
SELECT *
FROM NumberExtracted
ORDER BY ID,TheNumber;
第一个CTE使用字符串拆分通过XML获取原始字符串中的所有值(顺便说一句:从不存储以逗号分隔的值!)。
第二个CTE将使用相同的方法提取数字,类型安全为INT。
您最终可以在ORDER BY
中使用它。
结果:
+----+-----------+-----------+
| ID | OnePart | TheNumber |
+----+-----------+-----------+
| 1 | IS-1 | 1 |
+----+-----------+-----------+
| 1 | IS-12 | 12 |
+----+-----------+-----------+
| 1 | IS-123 | 123 |
+----+-----------+-----------+
| 1 | IS-123.11 | 123 |
+----+-----------+-----------+
| 1 | IS-123.a. | 123 |
+----+-----------+-----------+
| 2 | IS-870.a | 870 |
+----+-----------+-----------+
| 2 | IS-871.a | 871 |
+----+-----------+-----------+
| 2 | IS-872.a | 872 |
+----+-----------+-----------+
| 2 | IS-1170 | 1170 |
+----+-----------+-----------+
| 2 | IS-1171 | 1171 |
+----+-----------+-----------+
| 2 | IS-1172 | 1172 |
+----+-----------+-----------+
| 2 | IS-1173 | 1173 |
+----+-----------+-----------+
| 2 | IS-1174 | 1174 |
+----+-----------+-----------+
答案 2 :(得分:0)
IF OBJECT_ID(N'tempdb..##table1', N'U') IS NOT NULL
DROP TABLE ##table1;
create table ##table1(col1 varchar(20))
declare @query as nvarchar(max)
declare @var1 as varchar(max)='IS-1, IS-12, IS-123, IS-123.11, IS-123.a.,IS-1170, IS-1171, IS-1172, IS-1173, IS-1174, IS-870.a, IS-871.a, IS-872.a.'
set @var1=replace(@var1,',','''),(''')
set @var1='('''+@var1+''')'
set @var1=replace(@var1,' ','')
set @query='insert into ##table1 values'+@var1
EXEC sp_executesql @query
IF OBJECT_ID(N'tempdb..##table2', N'U') IS NOT NULL
DROP TABLE ##table2;
select * into ##table2 from ##table1 order by cast(replace(replace(replace(col1,'IS-',''),'.a.',''),'.a','') as float)
declare @results varchar(max)
select @results = coalesce(@results + ', ', '') + convert(varchar(12),col1) from ##table2
select @results
DROP TABLE ##table1
DROP TABLE ##table2