0

列に次のようなフィールドがあります。

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

4 に答える 4

1

この質問には問題がたくさんあります。基本的に、これらの文字列を見て、人間による解釈を行うことができる並べ替え関数を作成しようとしています。これは、最終的に命名スキーマが人間が理解できる方法で変更されることを意味しますが、コードは変更されず、バグが発生します。

あなたがどうしてこの道を行かないのか私にはわかりません。しかし、できる限り防御し、警告し、高めてください。

于 2012-06-30T15:39:19.137 に答える
0

使用できるトリックの1つは、文字列から先頭の整数を引き出し、整数値で並べ替えてから、文字列で並べ替えることです。

SQL Serverでこれを行う「簡単な」方法を知りません(つまり、関数を作成せずに)。

ネイティブの組み込みSQLServer関数を使用してこれを行う1つの方法は、PATINDEX関数を使用して「数字」と「非数字」の開始位置を検索し、それらの値を使用して先頭の整数の長さを決定することです。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文字列値を返す式のプレースホルダーです。

これは、テストケースで指定されたすべての値について、指定された要件を満たしています。

また、これは、「予期しない」値(たとえば、空の文字列''または先頭の整数のない文字列)が検出された場合に例外をスローしませ(つまり、ステートメントが失敗します)。

これは、文字列の「先頭の整数」部分のみを扱います。その後のすべてが文字列として比較されます。(つまり、「/1」<「/8」であるため、「6/10B」は「1/8B」の前にソートされます。

先行整数値の先行ゼロは、整数比較では無視され、文字列比較で考慮されます。(つまり、「05/9」は「5/8」の前にソートされます。これは、5 =5であるが「0」<「5」であるためです)

先頭に数字がない文字列値には、並べ替え操作でNULLの整数値が割り当てられるため、最初に並べ替えられます。

于 2012-06-29T20:58:08.637 に答える
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 以外の文字がある場合は、それを処理するためにスクリプトを変更する必要があります。

于 2012-06-29T17:04:08.717 に答える
0

並べ替え対象の列は文字データ型であると想定しています(一部の値は数値以外の文字であるため)-単純な ORDER BY が機能します

select '38a' as value
 union
select '12'
 union
select '1/2'
 union
select '1'
order by value

これはあなたが探している結果をあなたに与えませんか?

于 2012-06-29T17:10:38.360 に答える