Подтвердить что ты не робот

MySQL 'Order By' - сортировка буквенно-цифровых символов

Я хочу отсортировать следующие элементы данных в том порядке, в котором они представлены ниже (номера 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
4b9b3361

Ответ 1

Люди используют разные трюки для этого. Я Googled и узнаю некоторые результаты, которые следуют различным трюкам. Посмотрите на них:

Edit:

Я только что добавил код каждой ссылки для будущих посетителей.

Альфа-числовая сортировка в MySQL

Данный ввод

1A 1a 10A 9B 21C 1C 1D

Ожидаемый результат  

1A 1C 1D 1a 9B 10A 21C

Query

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

Натуральная сортировка в MySQL

Данный ввод

Table: sorting_test
 -------------------------- -------------
| alphanumeric VARCHAR(75) | integer 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           |
 -------------------------- -------------

Query

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

Query

SELECT version
FROM version_sorting
ORDER BY CAST(version AS UNSIGNED), version;

Надеюсь, что это поможет

Ответ 2

Я знаю, что этот пост закрыт, но я думаю, что мой путь может помочь некоторым людям. Итак, вот оно:

Мой набор данных очень похож, но немного сложнее. Он содержит цифры, буквенно-цифровые данные:

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 и сортировку с результатом.

Ответ 3

Просто сделайте следующее:

SELECT * FROM table ORDER BY column `name`+0 ASC

Добавление символа +0 означает, что:

0, 10, 11, 2, 3, 4

становится:

0, 2, 3, 4, 10, 11

Ответ 4

Я ненавижу это, но этот будет работать

order by lpad(name, 10, 0)  <-- assuming maximum string length is 10
                            <-- you can adjust to a bigger length if you want to

Ответ 5

У меня были хорошие результаты с

SELECT alphanumeric, integer FROM sorting_test ORDER BY CAST(alphanumeric AS UNSIGNED), alphanumeric ASC

Ответ 6

Этот вопрос задан ранее.

Тип сортировки, о котором вы говорите, называется "Естественная сортировка". Данные, которые вы хотите сортировать, являются буквенно-цифровыми. Было бы лучше создать новый столбец для сортировки.

Для дополнительной справки natural-sort-in-mysql

Ответ 7

Если вам нужно отсортировать буквенно-числовой столбец, который не имеет никакого стандартного формата

SELECT * FROM table ORDER BY (name = '0') DESC, (name+0 > 0) DESC, name+0 ASC, name ASC

Вы можете адаптировать это решение для включения поддержки не буквенно-цифровых символов при необходимости с использованием дополнительной логики.

Ответ 8

Это работает для типа данных: Data1, Data2, Data3......, Data21. Означает "Строка данных" является общей во всех строках.

Для ORDER BY ASC это будет отлично отсортировано, для ORDER BY DESC не подходит.

SELECT * FROM table_name ORDER BY LENGTH(column_name), column_name ASC;

Ответ 9

Это должно сортировать буквенно-цифровое поле, например: 1/Только номер, order by 1,2,3,4,5,6,7,8,9,10,11 и т.д.... 2/Затем поле с текстом вроде: 1foo, 2bar, aaa11aa, aaa22aa, b5452 и т.д.

SELECT  MyField
FROM MyTable
order by 
    IF( MyField REGEXP '^-?[0-9]+$' = 0, 
    9999999999 ,  
    CAST(MyField AS DECIMAL) 
    ), MyField

Запрос проверяет, являются ли данные числом, если не поместить его в 9999999999, затем сначала закажите его в этом столбце, затем закажите данные с текстом

Удачи!

Ответ 10

SELECT s.id, s.name, LENGTH (s.name) len, ASCII (s.name) ASCCCI FROM table_name s ORDER BY ASCCCI, len, NAME ASC;

Ответ 11

Вместо того, чтобы пытаться написать некоторую функцию и замедлить запрос 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

Ответ 12

Попробуйте это для ORDER BY DESC

SELECT * FROM testdata ORDER BY LENGHT(name) DESC, name DESC

Ответ 13

Я думаю, что тип данных столбца - это текст или что-то еще, что не отсортировано должным образом. измените его как int, bigint, float как числовой тип, чтобы он нормально функционировал...

SELECT * FROM table ORDER BY column name ASC