UFO ET IT

MySQL 'Order By'-올바른 영숫자 정렬

ufoet 2021. 1. 17. 11:35
반응형

MySQL 'Order By'-올바른 영숫자 정렬


다음 데이터 항목을 아래에 표시된 순서대로 정렬하고 싶습니다 (숫자 1-12).

1
2
4
5
6
7
8
9
10
11
12

그러나 내 쿼리는 order by xxxxx asc다른 모든 것보다 첫 번째 숫자로 정렬합니다.

1
10
11
12
2
4
5
6
7
8
9

더 적절하게 정렬하는 트릭이 있습니까?

또한 완전한 공개를 위해 문자와 숫자가 혼합되어있을 수 있습니다 (현재는 그렇지 않지만). 예 :

A1
534G
G46A
1,000 억
100A
100JE

기타....

감사!

업데이트 : 쿼리를 요청하는 사람들

select * from table order by name asc

사람들은이를 위해 다른 트릭을 사용합니다. 나는 구글을 검색하고 각각 다른 트릭을 따르는 일부 결과를 발견했습니다. 그들을보세요 :

편집하다:

향후 방문자를 위해 각 링크의 코드를 추가했습니다.

MySQL의 영숫자 정렬

주어진 입력

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

MySQL의 자연 정렬

주어진 입력

표 : 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


나는이 싫어,하지만 작동합니다

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

이러한 유형의 질문은 이전에 요청되었습니다.

당신이 말하는 분류 유형을 "자연 분류"라고합니다. 정렬하려는 데이터는 영숫자입니다. 정렬을 위해 새 열을 만드는 것이 좋습니다.

추가 도움이 필요하면 natural-sort-in-mysql을 확인하십시오.


표준 형식이없는 영숫자 열을 정렬해야하는 경우

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

추가 논리를 사용하여 원하는 경우 영숫자가 아닌 문자에 대한 지원을 포함하도록이 솔루션을 조정할 수 있습니다.


이것은 데이터 유형에 대해 작동합니다 : 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등 ... 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에 넣은 다음이 열에서 먼저 주문한 다음 텍스트로 데이터를 주문합니다.

행운을 빕니다!


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

DESC 주문을 위해 이것을 시도하십시오

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

참조 URL : https://stackoverflow.com/questions/8557172/mysql-order-by-sorting-alphanumeric-correctly

반응형