2

次のようなデータセットがあります。

+--------+
| Square |
+--------+
| A1     |
| A10    |
| A2     |
| A3     |
| A4     |
| A5     |
| A6     |
| A7     |
| A8     |
| A9     |
| B1     |
| B10    |
| B2     |
| B3     |
| B4     |
| B5     |
| B6     |
| B7     |
| B8     |
| B9     |

...

| AA1    |
| AA10   |
| AA2    |
| AA3    |
| AA4    |
| AA5    |
| AA6    |
| AA7    |
| AA8    |
| AA9    |
+--------+

プレフィックスは A#-Z# から始まり、AA#-ZZ# と続き、最大 2 文字です (つまり、ZZ を超えることはありません)。数字のサフィックスは任意の長さにすることができます (つまり、A1、A10、A100、A1000 など)。

これらを並べ替えて、結果セットを次のように表示するにはどうすればよいですか。

+--------+
| Square |
+--------+
| A1     |
| A2     |
| A3     |
| A4     |
| A5     |
| A6     |
| A7     |
| A8     |
| A9     |
| A10    |
| B1     |
| B2     |
| B3     |
| B4     |
| B5     |
| B6     |
| B7     |
| B8     |
| B9     |
| B10    |

...

| AA1    |
| AA2    |
| AA3    |
| AA4    |
| AA5    |
| AA6    |
| AA7    |
| AA8    |
| AA9    |
| AA10   |
+--------+
4

5 に答える 5

7

テーブルを再構築する必要があります。そうしないと、次のような非効率的なクエリになる可能性があります。

SELECT  Square
FROM    Table1
ORDER   BY         
        CASE WHEN Square REGEXP '^[A-Z]{2}'
            THEN 1 
            ELSE 0
        END ASC,
        CASE WHEN Square REGEXP '^[A-Z]{2}'
            THEN LEFT(Square, 2)
            ELSE LEFT(Square, 1)
        END ASC,
        CASE WHEN Square REGEXP '^[A-Z]{2}'
            THEN CAST(RIGHT(Square, LENGTH(Square) - 2) AS SIGNED)
            ELSE CAST(RIGHT(Square, LENGTH(Square) - 1) AS SIGNED)
        END ASC

または使用してIF

SELECT  Square
FROM    Table1
ORDER   BY Square REGEXP '^[A-Z]{2}' ASC,
           IF(Square REGEXP '^[A-Z]{2}', LEFT(Square, 2), LEFT(Square, 1)),
           CAST(IF(Square REGEXP '^[A-Z]{2}', RIGHT(Square, LENGTH(Square) - 2), RIGHT(Square, LENGTH(Square) - 1)) AS SIGNED)
于 2013-04-01T12:33:00.657 に答える
1

ここで、テーブルを構造化するより良い方法

 letter  number  
   A      1
   A      2
   A      3
  .....so on

あなたのクエリはそのように簡単になります

  select concat(letter,number) as Square from your_table
  order by letter , number

デモはこちら

于 2013-04-01T12:58:53.197 に答える
0

可能であれば、データベース構造を変更することを強くお勧めします。これらは 2 つの別々のフィールドに格納する必要があります。並べ替えを実行する方法を次に示しますが、テーブルを再構築するために正しい方向に進むこともできます。

select square, left(square,2) prefix, mid(square,3) suffix
from yourtable
where left(square,2) not regexp '[0-9]'
union
select square, left(square,1) prefix, mid(square,2) suffix
from yourtable
where left(square,2) regexp '[0-9]'
order by prefix, cast(sufix as signed)

SQL フィドルのデモ

このように、プレフィックスとサフィックスが分割されていることがわかります。これは、ユニオンなしの case/if ステートメントでも実行できます。

于 2013-04-01T12:40:53.333 に答える
0

私が間違っていなければ、これでうまくいくかもしれません:

SELECT Square
FROM table
ORDER BY CASE WHEN
     SUBSTR(Square, 2, 1) BETWEEN 'A' AND 'Z' 
     THEN CONCAT(LEFT(Square, 2),
         LPAD(RIGHT(Square, LENGTH(Square) - 2), 6, '000000'))
     ELSE CONCAT(LEFT(Square, 1),
         LPAD(RIGHT(Square(LENGTH(Square) - 1), 6, '000000'))
    END
于 2013-04-01T12:12:59.807 に答える
-1

現在、これを完全にテストする方法はありませんが、私にとっては機能しており、前のソリューションとはまったく異なるソリューションです. 私のものは非常に似ていて、db構造を変更することはオプションではありません。ソートしているのはユーザー入力です...しかし、私のソリューションはサイズに関係なく機能し、提案されたものよりもはるかに簡単です:

SELECT  Square
FROM    Table1
ORDER BY LENGTH(Square), Square
于 2016-09-14T21:07:19.053 に答える