我在列中的字段看起来像这样:
2/8B, 3, 3/8B, 4/8B, 2, 6, 4/9, 9, 8/9, 8, 7, 1, 5/9, 10, 3/9, 2/9, 7/9, 6/8B, 6/9, 1/9, 5, 8B, 5/8B, 4
我需要以下列方式对此列表进行排序:
1, 1/9, 2, 2/8B, 2/9, 3, 3/8B, 3/9, 4, 4/8B, 4/9, 5, 5/8B, 5/9, 6, 6/8B, 6/9, 7, 7/9, 8, 8/9, 8B, 9, 10
如何订购以创建此输出?
清除任何混淆(1/2)不是一个分数。 “/”只是一个分隔符。
答案 0 :(得分:1)
这个问题充满了问题。基本上你正在尝试编写一个排序函数,它可以查看这些字符串并对它们进行人工解释。这意味着最终命名模式将以任何人理解的方式发生变化,但是您的代码不会,然后您就会有错误。
我不知道你怎么不走这条路。但是尽可能地捍卫和警告并提升。
答案 1 :(得分:0)
我不明白;使用您提供的字符按照您请求的顺序排序。试一试:
SELECT Test
FROM (
SELECT '38a' AS Test
UNION
SELECT '1'
UNION
SELECT '1/2'
UNION
SELECT '12'
) MyData
ORDER BY Test ASC
击> <击> 撞击>
修改强>
现在你已经给出了具体的例子,我发现10
和8B
正在抛弃这些东西。试试这个:
SELECT YourCol
FROM YourTable
ORDER BY CAST(REPLACE(REPLACE(REPLACE(YourCol, 'B', '.99'), '/', '.'),
'.8.99', '.899') AS NUMERIC(18, 4))
这将命令为:
1,1 / 9,2,2 / 8B,2 / 9,3,3 / 8B,3 / 9,4,4 / 8B,4 / 9,5,5 / 8B,5 / 9,6 ,6 / 8B,6 / 9,7,7 / 9,8,8 / 9,8B,9,10
这很难看,但它确实有效。如果除了B之外还有其他字母,则必须更改脚本以处理该字母。
答案 2 :(得分:0)
我假设您要排序的列是字符数据类型(因为某些值是非数字字符) - 所以简单的ORDER BY将起作用
select '38a' as value
union
select '12'
union
select '1/2'
union
select '1'
order by value
这不能为您提供您正在寻找的结果吗?
答案 3 :(得分:0)
您可以使用的一个技巧是从字符串中提取前导整数,按整数值排序,然后按字符串排序。
我不知道在SQL Server中执行此操作的任何“简单”方法(即没有构建函数)。
使用本机内置SQL Server函数执行此操作的一种方法是使用PATINDEX函数搜索“digits”和“non-digits”的起始位置,然后使用这些值来确定前导整数的长度。使用SUBSTRING和CONVERT函数提取前导整数值。
它不漂亮:
ORDER BY
CASE WHEN PATINDEX('[0-9]%', t.str ) = 1
THEN
CASE WHEN PATINDEX('%[^0-9]%', t.str ) > 0
THEN CONVERT(INTEGER,SUBSTRING( t.str ,1,PATINDEX('%[^0-9]%', t.str )-1))
ELSE CONVERT(INTEGER, t.str )
END
ELSE NULL
END
, t.str
说明:
t.str
是表达式的占位符,用于返回字符串值。
对于测试用例中给出的所有值,这符合指定的要求。
此外,当遇到“意外”值时,不会抛出异常(即导致语句失败),例如,空字符串''或没有前导整数的字符串。< / p>
这只处理字符串的“前导整数”部分。之后的所有内容都被比作字符串。 (这意味着例如'6 / 10B'将在'1 / 8B'之前排序,因为'/ 1'&lt;'/ 8'。
整数比较将忽略前导整数值的任何前导零,并在字符串比较时考虑。 (这意味着例如'05 / 9'将在'5/8'之前排序,因为5 = 5但是'0'&lt;'5')
任何没有前导数字的字符串值都将为排序操作分配一个NULL的整数值,因此这些值将首先排序。