文字列列(を含む数値)をソートしようとしています。
// SELECT `name` FROM `mytable` ORDER BY `name` ASC
+----------+
+-- name --+
+----------+
+-- a 1 ---+
+-- a 12 --+
+-- a 2 ---+
+-- a 3 ---+
Mysqlの自然なソートアルゴリズムがa 12
後a 1
(これはほとんどのアプリで問題ありません)、しかし私には固有のニーズがあるため、結果をこのようにソートする必要があります。
+----------+
+-- name --+
+----------+
+-- a 1 ---+
+-- a 2 ---+
+-- a 3 ---+
+-- a 12 --+
SQLのみで可能ですか、それともアプリケーションレベルで結果セットを操作する必要がありますか?
仮定に行くと、これは常にWord_space_NUMBERですこれはうまくいくはずです:
SELECT *
FROM table
ORDER BY CAST(SUBSTRING(column,LOCATE(' ',column)+1) AS SIGNED)
[〜#〜] position [〜#〜] を使用してスペースを検索し、 [〜#〜] substring [〜#〜] を使用してその後の数値を取得し、 [〜#〜] cast [〜#〜] 比較可能な値にします。
列に別のパターンがある場合は、お知らせください。より良い回避策を考案します。
[〜#〜] edit [〜#〜]動作することが証明されています:
mysql> INSERT INTO t (st) VALUES ('a 1'),('a 12'),('a 6'),('a 11');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t ORDER BY st;
+----+------+
| id | st |
+----+------+
| 1 | a 1 |
| 4 | a 11 |
| 2 | a 12 |
| 3 | a 6 |
+----+------+
4 rows in set (0.00 sec)
mysql> SELECT * FROM t ORDER BY CAST(SUBSTRING(st,LOCATE(' ',st)+1) AS SIGNED);
+----+------+
| id | st |
+----+------+
| 1 | a 1 |
| 3 | a 6 |
| 4 | a 11 |
| 2 | a 12 |
+----+------+
mysql> INSERT INTO t (st) VALUES ('b 1'),('b 12'),('b 6'),('b 11');
Query OK, 4 rows affected (0.00 sec)
Records: 4 Duplicates: 0 Warnings: 0
mysql> SELECT * FROM t ORDER BY CAST(SUBSTRING(st,LOCATE(' ',st)+1) AS SIGNED);
+----+------+
| id | st |
+----+------+
| 1 | a 1 |
| 5 | b 1 |
| 3 | a 6 |
| 7 | b 6 |
| 4 | a 11 |
| 8 | b 11 |
| 2 | a 12 |
| 6 | b 12 |
+----+------+
8 rows in set (0.00 sec)
mysql> SELECT * FROM t ORDER BY LEFT(st,LOCATE(' ',st)), CAST(SUBSTRING(st,LOCATE(' ',st)+1) AS SIGNED);
+----+------+
| id | st |
+----+------+
| 1 | a 1 |
| 3 | a 6 |
| 4 | a 11 |
| 2 | a 12 |
| 5 | b 1 |
| 7 | b 6 |
| 8 | b 11 |
| 6 | b 12 |
+----+------+
8 rows in set (0.00 sec)
私の不完全なテーブル/列名を無視しますが、正しい結果が得られます。また、少し進んで、文字の接頭辞を数値で区切るために二重ソートを追加しました。
編集SUBSTRING_INDEX
は少し読みやすくします。
ORDER BY SUBSTRING_INDEX(st, " ", 1) ASC, CAST(SUBSTRING_INDEX(st, " ", -1) AS SIGNED)
あなたはこれを試すことができます:
ORDER BY CASE
WHEN ISNUMERIC(column) THEN cast(column as int)
else ascii(column[1,1])
end
MySQL CAST/Convert 関数を見てください。
SELECT name FROM mytable ORDER BY CAST(name AS INTEGER) ASC;
編集:私は読んだ:
文字列列(数値を含む)をソートしようとしています。
...しかし、結果セットを見てみました。 a
も実際にはコンテンツの一部ですか?その場合、 [〜#〜] mid [〜#〜] のような関数を使用して、数値のみを抽出し、それをキャストできます。
しかし、allの行にa
のみが含まれ、変化がない場合は、省略してもよいでしょう...
別のオプションとして、数値の左側にスペースを文字列に埋め込んで(Wordと数値の間にスペースを追加する)、結果の文字列を使用してソートすることもできます。次のようになります。
ORDER BY INSERT(
column,
LOCATE(' ', column),
0,
SPACES(20 - LENGTH(column) + LOCATE(' ', column))
)
文字列は「Wordの後にスペースが続き、その後に数値が続く」というパターンであると見なされ、数値は負でないと見なされます(そうしないと、正しくソートされません)。ハードコードされた20
は任意に選択され、文字列の数値部分の可能な最大長であると想定されています。
ここで、Convertを使用して次のクエリで別のソリューションを見つけました
select * from tablename where columnname like '%a%' order by Convert(smallint,Replace(columnname,'a',''))