次のデータ項目を、以下に示す順序(番号1〜12)で並べ替えます。
1 2 3 4 5 6 7 8 9 10 11 12
ただし、私のクエリ-order by xxxxx asc
を使用すると、最初の数字でソートされます。
1 10 11 12 2 3 4 5 6 7 8 9
それをより適切にソートするためのトリックはありますか?
さらに、完全な開示のために、これは文字と数字の組み合わせである可能性があります(ただし、現時点ではそうではありません)。
A1 534G G46A 100B 100A 100JE
等....
ありがとう!
更新:問い合わせをする人
select * from table order by name asc
これを行うには、さまざまなトリックを使用します。私はグーグルで検索し、それぞれが異なるトリックに従う結果を見つけました。それらを見てください:
編集:
将来の訪問者のために各リンクのコードを追加しました。
与えられた入力
1A 1a 10A 9B 21C 1C 1D
期待される出力
1A 1C 1D 1a 9B 10A 21C
クエリ
Bin Way
===================================
SELECT
tbl_column,
BIN(tbl_column) AS binray_not_needed_column
FROM db_table
ORDER BY binray_not_needed_column ASC , tbl_column ASC
-----------------------
Cast Way
===================================
SELECT
tbl_column,
CAST(tbl_column as SIGNED) AS casted_column
FROM db_table
ORDER BY casted_column ASC , tbl_column ASC
与えられた入力
テーブル:sorting_test -------------------------- ------------- |英数字VARCHAR(75)|整数INT | -------------------------- ------------- | test1 | 1 | | test12 | 2 | | test13 | 3 | | test2 | 4 | | test3 | 5 | -------------------------- -------------
期待される出力
-------------------------- -------------
| alphanumeric VARCHAR(75) | integer INT |
-------------------------- -------------
| test1 | 1 |
| test2 | 4 |
| test3 | 5 |
| test12 | 2 |
| test13 | 3 |
-------------------------- -------------
クエリ
SELECT alphanumeric, integer
FROM sorting_test
ORDER BY LENGTH(alphanumeric), alphanumeric
与えられた入力
2a, 12, 5b, 5a, 10, 11, 1, 4b
期待される出力
1, 2a, 4b, 5a, 5b, 10, 11, 12
クエリ
SELECT version
FROM version_sorting
ORDER BY CAST(version AS UNSIGNED), version;
お役に立てれば
私はこの投稿が閉じられていることを知っていますが、私のやり方は何人かの人々を助けることができると思います。だからそれは:
私のデータセットは非常に似ていますが、もう少し複雑です。数字、英数字データがあります:
1
2
Chair
3
0
4
5
-
Table
10
13
19
Windows
99
102
Dog
最初に「-」記号、次に数字、次にテキストを付けたいと思います。
だから私はこのように行きます:
SELECT name, (name = '-') boolDash, (name = '0') boolZero, (name+0 > 0) boolNum
FROM table
ORDER BY boolDash DESC, boolZero DESC, boolNum DESC, (name+0), name
結果は次のようになります。
-
0
1
2
3
4
5
10
13
99
102
Chair
Dog
Table
Windows
全体のアイデアは、SELECTに簡単なチェックを行い、結果でソートすることです。
これを行うだけです:
SELECT * FROM table ORDER BY column `name`+0 ASC
+0を追加すると、次のことを意味します。
0、10、11、2、3、4
になります:
0、2、3、4、10、11
私はこれが嫌いですが、 this は機能します
order by lpad(name, 10, 0) <-- assuming maximum string length is 10
<-- you can adjust to a bigger length if you want to
私はいくつかの良い結果が得られました
SELECT alphanumeric, integer FROM sorting_test ORDER BY CAST(alphanumeric AS UNSIGNED), alphanumeric ASC
標準形式をまったく持たない英数字列をソートする必要がある場合
SELECT * FROM table ORDER BY (name = '0') DESC, (name+0 > 0) DESC, name+0 ASC, name ASC
必要に応じて、追加のロジックを使用して、英数字以外の文字のサポートを含めるようにこの解決策を調整できます。
このタイプの質問は以前に尋ねられました。
あなたが話しているソートのタイプは「自然ソート」と呼ばれます。ソートするデータは英数字です。ソート用の新しい列を作成することをお勧めします。
さらにヘルプを確認するには natural-sort-in-mysql
これは、データのタイプ:Data1、Data2、Data3 ......、Data21で機能します。意味「データ」文字列はすべての行で共通です。
ORDER BY ASCの場合は完全にソートされ、ORDER BY DESCの場合は適切ではありません。
SELECT * FROM table_name ORDER BY LENGTH(column_name), column_name ASC;
これは次のように英数字フィールドをソートする必要があります:1 /数値のみ、order by 1,2,3,4,5,6,7,8,9,10,11
etc ... 2 /次に、次のようなテキストを持つフィールド:1foo, 2bar, aaa11aa, aaa22aa, b5452
etc ...
SELECT MyField
FROM MyTable
order by
IF( MyField REGEXP '^-?[0-9]+$' = 0,
9999999999 ,
CAST(MyField AS DECIMAL)
), MyField
クエリは、データが数値であるかどうかを確認し、数値が9999999999になっていない場合は、この列で最初に注文し、次にテキスト付きのデータで注文します
幸運を!
SELECT s.id、s.name、LENGTH(s.name)len、ASCII(s.name)ASCCCI FROM table_name s ORDER BY ASCCCI、len、NAME ASC;
関数を書いてSELECT
クエリを遅くする代わりに、これを行う別の方法を考えました...
次のクラスからの結果を保持するデータベースに追加フィールドを作成し、新しい行を挿入するときに、このクラスで自然にソートされるフィールド値を実行し、その結果を追加フィールドに保存します。次に、元のフィールドでソートする代わりに、追加のフィールドでソートします。
String nsFieldVal = new NaturalSortString(getFieldValue(), 4).toString()
_The above means:
- Create a NaturalSortString for the String returned from getFieldValue()
- Allow up to 4 bytes to store each character or number (4 bytes = ffff = 65535)
| field(32) | nsfield(161) |
a1 300610001
_
String sortString = new NaturalSortString(getString(), 4).toString()
_import StringUtils;
/**
* Creates a string that allows natural sorting in a SQL database
* eg, 0 1 1a 2 3 3a 10 100 a a1 a1a1 b
*/
public class NaturalSortString {
private String inStr;
private int byteSize;
private StringBuilder out = new StringBuilder();
/**
* A byte stores the hex value (0 to f) of a letter or number.
* Since a letter is two bytes, the minimum byteSize is 2.
*
* 2 bytes = 00 - ff (max number is 255)
* 3 bytes = 000 - fff (max number is 4095)
* 4 bytes = 0000 - ffff (max number is 65535)
*
* For example:
* dog123 = 64,6F,67,7B and thus byteSize >= 2.
* dog280 = 64,6F,67,118 and thus byteSize >= 3.
*
* For example:
* The String, "There are 1000000 spots on a dalmatian" would require a byteSize that can
* store the number '1000000' which in hex is 'f4240' and thus the byteSize must be at least 5
*
* The dbColumn size to store the NaturalSortString is calculated as:
* > originalStringColumnSize x byteSize + 1
* The extra '1' is a marker for String type - Letter, Number, Symbol
* Thus, if the originalStringColumn is varchar(32) and the byteSize is 5:
* > NaturalSortStringColumnSize = 32 x 5 + 1 = varchar(161)
*
* The byteSize must be the same for all NaturalSortStrings created in the same table.
* If you need to change the byteSize (for instance, to accommodate larger numbers), you will
* need to recalculate the NaturalSortString for each existing row using the new byteSize.
*
* @param str String to create a natural sort string from
* @param byteSize Per character storage byte size (minimum 2)
* @throws Exception See the error description thrown
*/
public NaturalSortString(String str, int byteSize) throws Exception {
if (str == null || str.isEmpty()) return;
this.inStr = str;
this.byteSize = Math.max(2, byteSize); // minimum of 2 bytes to hold a character
setStringType();
iterateString();
}
private void setStringType() {
char firstchar = inStr.toLowerCase().subSequence(0, 1).charAt(0);
if (Character.isLetter(firstchar)) // letters third
out.append(3);
else if (Character.isDigit(firstchar)) // numbers second
out.append(2);
else // non-alphanumeric first
out.append(1);
}
private void iterateString() throws Exception {
StringBuilder n = new StringBuilder();
for (char c : inStr.toLowerCase().toCharArray()) { // lowercase for CASE INSENSITIVE sorting
if (Character.isDigit(c)) {
// group numbers
n.append(c);
continue;
}
if (n.length() > 0) {
addInteger(n.toString());
n = new StringBuilder();
}
addCharacter(c);
}
if (n.length() > 0) {
addInteger(n.toString());
}
}
private void addInteger(String s) throws Exception {
int i = Integer.parseInt(s);
if (i >= (Math.pow(16, byteSize)))
throw new Exception("naturalsort_bytesize_exceeded");
out.append(StringUtils.padLeft(Integer.toHexString(i), byteSize));
}
private void addCharacter(char c) {
//TODO: Add rest of accented characters
if (c >= 224 && c <= 229) // set accented a to a
c = 'a';
else if (c >= 232 && c <= 235) // set accented e to e
c = 'e';
else if (c >= 236 && c <= 239) // set accented i to i
c = 'i';
else if (c >= 242 && c <= 246) // set accented o to o
c = 'o';
else if (c >= 249 && c <= 252) // set accented u to u
c = 'u';
else if (c >= 253 && c <= 255) // set accented y to y
c = 'y';
out.append(StringUtils.padLeft(Integer.toHexString(c), byteSize));
}
@Override
public String toString() {
return out.toString();
}
}
_
完全を期すために、以下に_StringUtils.padLeft
_メソッドを示します。
_public static String padLeft(String s, int n) {
if (n - s.length() == 0) return s;
return String.format("%0" + (n - s.length()) + "d%s", 0, s);
}
_
結果は次のようになります
_-1
-a
0
1
1.0
1.01
1.1.1
1a
1b
9
10
10a
10ab
11
12
12abcd
100
a
a1a1
a1a2
a-1
a-2
áviacion
b
c1
c2
c12
c100
d
d1.1.1
e
_