숫자로 된 SQL 주문 문자열


137

VARCHARMySQL 데이터베이스에 저장된 숫자가 있습니다. INT상황에 따라 다른 것으로 만들 수 없습니다 .

정렬하는 동안 숫자가 아닌 문자로 사용합니다.

데이터베이스에서 나는

1 2 3 4 5 6 7 8 9 10...

내 페이지에는 다음과 같은 순서 목록이 표시됩니다.

1 10 2 3 4 5 6 7 8 9

숫자가 오름차순으로 표시되도록하려면 어떻게해야합니까?


5
반드시 문자열 대신 숫자로 데이터를 저장해야합니다.
Oded

@Oded 매우 특별한 경우에만 숫자 값으로 정렬하려는 임의의 데이터 (예 : 설정)를 가질 수 있습니다.
Glutexo

매우 흥미로운 기사 - MSSQL입니다하지만 MySQL은 상대적으로 비슷해야합니다 essentialsql.com/use-sql-server-to-sort-alphanumeric-values
AquaAlex

답변:


256

가능하면 숫자 만 저장하는 경우 가능하면 열의 데이터 유형을 숫자로 변경해야합니다.

당신이 할 수없는 경우 다음에 열 값을 캐스팅 integer 명시 적 으로

select col from yourtable
order by cast(col as unsigned)

또는 암시 적 으로 예를 들어 수로 변환하는 수학적 연산으로

select col from yourtable
order by col + 0

BTW MySQL은 문자열을 왼쪽에서 오른쪽으로 변환합니다. 예 :

string value  |  integer value after conversion
--------------+--------------------------------
'1'           |  1
'ABC'         |  0   /* the string does not contain a number, so the result is 0 */
'123miles'    |  123 
'$123'        |  0   /* the left side of the string does not start with a number */

3
col * 1로 주문하면 완벽하게 작동합니다. 이 뒤에 숨겨진 마법은 무엇입니까? 죄송하지만 전문가가 아니기 때문에 어리석은 질문 일 수 있지만 * 1은 어떻게 숫자로 변경됩니까?
Jamol

12
MySQL은 자동으로 문자열을 숫자로 변환하여 곱셈을합니다.1
juergen d

1
첫 번째 옵션은 가장 적합한 옵션이고, 두 번째 옵션에는 추가 단계가 있지만 덜 작동합니다.
Manatax

5
문자열과 숫자가 혼합되어 있고 둘 다 정렬하려면 "col by order * 1, col"
Hayden Thring

1
@superphonic : 결과는입니다 decimal.
juergen d

70

단일 캐스트를 사용하지 않는 다른 방법.

(주조가 허용되지 않는 JPA 2.0을 사용하는 사람)

select col from yourtable
order by length(col),col

편집 : 양의 정수에 대해서만 작동


9
이것은 int와 string을 모두 포함하는 컬럼으로 작동하는 좋은 방법입니다.
Sruit A.Suk

1
모든 경우에 작동하지는 않습니다. 머리 꼭대기에서, 작동하지 않는 경우는 정수와 혼합입니다. 음수, 앞에 0이있는 숫자, 분수가있는 숫자 및 단어와 숫자가 결합 된 숫자입니다.
WonderWorker

3
주변의 모든 주조 및 저글링 종류없이 훌륭한 솔루션, 한
막심 Luzik

첫눈에 작동하지 않는 것 같았지만 작동했습니다! 감사합니다!
try2fly.b4ucry


17

내가 정렬하는 열에는 알파와 숫자의 조합이 있으므로이 게시물의 제안을 시작점으로 사용하여이를 제안했습니다.

DECLARE @tmp TABLE (ID VARCHAR(50));
INSERT INTO @tmp VALUES ('XYZ300');
INSERT INTO @tmp VALUES ('XYZ1002');
INSERT INTO @tmp VALUES ('106');
INSERT INTO @tmp VALUES ('206');
INSERT INTO @tmp VALUES ('1002');
INSERT INTO @tmp VALUES ('J206');
INSERT INTO @tmp VALUES ('J1002');

SELECT ID, (CASE WHEN ISNUMERIC(ID) = 1 THEN 0 ELSE 1 END) IsNum
FROM @tmp
ORDER BY IsNum, LEN(ID), ID;

결과

ID
------------------------
106
206
1002
J206
J1002
XYZ300
XYZ1002

도움이 되었기를 바랍니다


1 - ISNUMERIC(ID)대신 (CASE WHEN ISNUMERIC(ID) = 1 THEN 0 ELSE 1 END)0을 1로 바꾸고 그 반대로 바꾸는 대신 간단하게 사용할 수 있습니다 .
S.Serpooshan

7

이것은 나를 위해 작동합니다.

select * from tablename
order by cast(columnname as int) asc

이유를 설명 할 수 있습니까?
Slavik

가장 간단한 대답은, 정확히 필요한 것을 수행하고, 문자열을 int로 캐스트 한 다음, 그 int에 의해 오름차순으로 정렬하고, 펑키 한 물건은 없음 :)
denford mutseriwa

4

변환하는 또 다른 방법.

문자열 필드가있는 경우 다음과 같은 방법으로 필드 또는 숫자 부분을 변환 할 수 있습니다. 모든 정수 문자열을 동일한 길이로 만들려면 앞에 0을 추가하십시오.

ORDER BY CONCAT( REPEAT(  "0", 18 - LENGTH( stringfield ) ) , stringfield ) 

또는 'tensymbols13', 'tensymbols1222'등과 같은 필드의 일부로 주문하십시오.

ORDER BY CONCAT( REPEAT(  "0", 18 - LENGTH( LEFT( stringfield , 10 ) ) ) , LEFT( stringfield , 10 ) ) 

2

나는 또한 문자 접두사가있는 정렬 필드를 찾고있었습니다. 여기 내가 해결책을 찾은 것이 있습니다. 이것은 누가 같은 솔루션을 찾는 데 도움이 될 수 있습니다.

필드 값 :

FL01,FL02,FL03,FL04,FL05,...FL100,...FL123456789

select SUBSTRING(field,3,9) as field from table order by SUBSTRING(field,3,10)*1 desc

SUBSTRING(field,3,9) 9는 최대 9 자리 정수 값을 보유하기에 충분하기 때문에 9를 넣습니다.

결과는 123456789 123456788 123456787 ... 100 99 ... 2 1입니다.


2

음수, 분수, 문자열 등 모든 것을 처리합니다.

ORDER BY ISNUMERIC(col) DESC, Try_Parse(col AS decimal(10,2)), col;

2

누가 동일한 솔루션을 찾는 데 도움이 될 수 있습니다.

select * from tablename ORDER BY ABS(column_name)

0

AdonisJS를 사용하고 ABC-202, ABC-201 ...과 같은 ID를 혼합 한 경우 원시 쿼리를 Query Builder와 결합하고 위의 솔루션을 구현할 수 있습니다 ( https://stackoverflow.com/a/25061144/4040835 ) 다음과 같이 :

const sortField =
  'membership_id'
const sortDirection =
  'asc'
const subquery = UserProfile.query()
  .select(
    'user_profiles.id',
    'user_profiles.user_id',
    'user_profiles.membership_id',
    'user_profiles.first_name',
    'user_profiles.middle_name',
    'user_profiles.last_name',
    'user_profiles.mobile_number',
    'countries.citizenship',
    'states.name as state_of_origin',
    'user_profiles.gender',
    'user_profiles.created_at',
    'user_profiles.updated_at'
  )
  .leftJoin(
    'users',
    'user_profiles.user_id',
    'users.id'
  )
  .leftJoin(
    'countries',
    'user_profiles.nationality',
    'countries.id'
  )
  .leftJoin(
    'states',
    'user_profiles.state_of_origin',
    'states.id'
  )
  .orderByRaw(
    `SUBSTRING(:sortField:,3,15)*1 ${sortDirection}`,
    {
      sortField: sortField,
    }
  )
  .paginate(
    page,
    per_page
  )

참고 : 이 줄에서 : SUBSTRING(:sortField:,3,15)*1 ${sortDirection},

  1. '3' 은 숫자 앞에있는 마지막 숫자가 아닌 문자의 색인 번호를 나타냅니다. 혼합 ID가 "ABC-123"인 경우 색인 번호는 4입니다.
  2. '15' 는 하이픈 다음에 가능한 한 많은 자릿수를 포착하는 데 사용됩니다.
  3. '1' 은 부분 문자열을 숫자로 효과적으로 캐스트하는 부분 문자열에서 수학 연산을 수행합니다.

1 참고 : 현재 원시 쿼리에서 매개 변수 바인딩에 대한 자세한 읽을 수 있습니다 : https://knexjs.org/#Raw-Bindings 참조 2 : 아도니스 원시 쿼리 : https://adonisjs.com/docs/4.1/query-builder# _raw_queries


-3

필드를 VARCHAR 대신 INT로 변경하십시오.

다른 상황에 따라 INT를 만들 수 없습니다.

그런 다음 먼저 상황에 따라 수정하십시오. 그렇지 않으면 실제 기본 문제를 해결하는 중입니다. MySQL CAST를 사용하는 것이 옵션이지만 수정해야 할 잘못된 스키마를 숨 깁니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.