当列不是同一类型时,如何按列排序?

时间:2012-06-29 16:53:04

标签: tsql sql-server-2005

我在列中的字段看起来像这样:

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)不是一个分数。 “/”只是一个分隔符。

4 个答案:

答案 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

<击>

修改

现在你已经给出了具体的例子,我发现108B正在抛弃这些东西。试试这个:

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的整数值,因此这些值将首先排序。