web-dev-qa-db-ja.com

MySQLでのvarcharフィールドの数値ソート

タイプnumberのフィールドvarcharがあります。タイプはvarcharですが、オプションの先行ゼロ付きの整数値を格納します。ソートはそれらを辞書式に並べます("42" 前に来る "9")。数値("9"の前に来る"42")?

現在、私はクエリを使用しています:

SELECT * FROM table ORDER BY number ASC
37
wow

これを行うにはいくつかの方法があります。

  1. 文字列ではなく数値として保存します。 00100のような文字列を先頭のゼロでそのままにしておきたいので、すでにそれを割り引いています。
  2. 数値としてキャストされた文字列による順序。これは機能しますが、適切なサイズのデータ​​ベースのパフォーマンスを低下させることに注意してください。行ごとの関数は実際にはうまくスケーリングしません。
  3. 3番目の列を追加します。これは、文字列に相当する数値とそのインデックスです。次に、insert/updateトリガーを使用して、文字列列が変更されるたびに正しく設定されるようにします。

データベースの大部分は書き込まれるよりもはるかに頻繁に読み取られるため、上記の3番目のオプションは、すべての選択に対して計算コスト(insert/updateで行われます)を償却します。選択は、数値列を使用して順序付けするため(行ごとの関数は使用しない)、目もくらむほど高速です。

挿入と更新は遅くなりますが、それはあなたが支払う価格であり、正直なところ、支払う価値は十分にあります。

トリガーを使用すると、2つの列が段階的に保持されるため、テーブルのACIDプロパティが維持されます。そして、ほとんどのパフォーマンス最適化において、スペースと時間をトレードオフできることはよく知られているイディオムです。

この「トリック」は、(tolowerのようなものを使用する代わりに)姓の小文字バージョンを保存するなど、多くの状況で使用しました。 1つ(lenを使用する代わりに)など。

結果を理解(および軽減)することを条件に、パフォーマンスのために3番目の通常の形式から戻すことは可能です。

37
paxdiablo

これを試して

SELECT * FROM table_name ORDER BY CAST(field_name as SIGNED INTEGER) ASC
67
bobs

実際に私は何か面白いものを見つけました:

SELECT * FROM mytable ORDER BY LPAD(LOWER(mycol), 10,0) DESC

これにより、次のようにフィールドを注文できます。

1
2
3
10
A
A1
B2
10A
111
28
workdreamer
SELECT * FROM table ORDER BY number + 0
19
shantanuo

学んだばかりのトリック。 varcharフィールドの順序句に「+0」を追加します。

SELECT * FROM table ORDER BY number+0 ASC

今、この答えが上にあります。これがフィールドと整数を型キャストしているのだろうかと思っています。パフォーマンスを比較していません。すばらしい。

16
alexii

Er353、ER 280、ER 30などの値を持つテーブルの場合、デフォルトのソートではER280 ER30 ER353 ER36になります

SELECT fieldname, SUBSTRING(fieldname, 1, 2) AS bcd, 
CONVERT(SUBSTRING(fieldname, 3, 9), UNSIGNED INTEGER) AS num 
FROM table_name
ORDER BY bcd, num;

結果はこの順序になりますER30 ER36 ER280 ER353

5
ChAnDu353

次のSQLクエリを使用して、要件に応じて注文を取得できます

SELECT * FROM mytable ORDER BY ABS(mycol)
1

次のようなusernameを含む列VARCHARが与えられた場合:

username1
username10
username100

できること:

SELECT username,
CONVERT(REPLACE(username, 'username', ''), UNSIGNED INTEGER) AS N
FROM users u
WHERE username LIKE 'username%'
ORDER BY N;

それは安くはありませんが、仕事をします。

1
minusf
SELECT * FROM table ORDER BY number ASC

表示したいものを表示する必要があります。idでソートしているように見えるか、numberが現在integerとして定義されていません。

0
Or Weinberger