mySQL에서 사용자 정의 ORDER BY 주문을 정의하는 방법


143

MySQL에서는 어떻게 사용자 정의 정렬 순서를 정의합니까?

내가 원하는 것을 설명하기 위해이 표를 고려하십시오.

ID  Language    Text
0   ENU         a
0   JPN         b
0   DAN         c       
1   ENU         d
1   JPN         e
1   DAN         f
2   etc...

여기서 Language = ENU가 먼저 오게 한 다음 JPN 및 마지막으로 DAN이되도록 언어 및 오름차순으로 정렬 된 모든 행을 반환하고 싶습니다.

결과는 a, d, b, e, c, f 등이어야합니다.

이것도 가능합니까?

답변:


276

MySQL에는 FIELD()이와 같은 작업에 탁월한 편리한 기능 이 있습니다.

ORDER BY FIELD(Language,'ENU','JPN','DAN'), ID

그러나

  1. 다른 DBMS에는 이러한 기능이 없을 수 있으므로 SQL의 이식성이 떨어집니다.

  2. 언어 목록 (또는 정렬 할 다른 값)이 훨씬 길어지면 정렬 순서 열이 포함 된 별도의 테이블을 만들고 쿼리를 위해 정렬하는 것이 좋습니다.


3
고마워 이것은 두 가지 값 (JPN과 같은 기본 언어와 ENU와 같은 대체 언어)으로 주문 해야하는 상황에 완벽하게 적용됩니다.
Muleskinner

4
남자 당신은 나에게 :) 젠토에 재 저장
에릭 Simonic을

1
당신이 GROUP BY전에 있다면 ? 예를 들어, 원하는 첫 번째 값이 끝에 나타 납니까?
Pathros

쿼리를 GROUP BY하위 쿼리에 넣고 외부 쿼리에
정렬

1
매력처럼 작동 :)
Brane

53

그는 세 개의 값은 경우에, 당신은 사용할 수 있습니다 표현 :CASE

ORDER BY `ID`,
         CASE `Language`
         WHEN 'ENU' THEN 1
         WHEN 'JPN' THEN 2
         WHEN 'DAN' THEN 3
         END

(다른 값이있을 수있는 경우 순서를 일관되게 유지하기 위해 몇 가지 논리를 추가 할 수 있습니다. 예를 들어 ELSE 4해당 CASE표현식에 추가 한 다음 Language자체적으로 세 번째 순서 기준으로 순서 를 지정할 수 있습니다 .

ORDER BY `ID`,
         CASE `Language`
         WHEN 'ENU' THEN 1
         WHEN 'JPN' THEN 2
         WHEN 'DAN' THEN 3
         ELSE 4
         END,
         `Language`

)


1
그리고 많은 언어 값이 있다면 각 언어와 정렬 순서 열을 저장하는 별도의 테이블을 가질 수 있으며 그에 연결됩니다
kaj

1
이것은 우선 ID별로 주문하여 a, b, c, d, e, f를 생성합니다.
piotrn

감사합니다. 이것이 완벽하게 작동합니다-Mchl이 더 단순 해 보인 대답에 따라
Muleskinner

19

몇 가지 옵션이 있습니다. 첫 번째는 언어를 ENUM으로 변경하는 것입니다 (이것이 가능하다고 가정하고 약간의 변형 만 예상합니다)

당신이 그것을 지정하는 경우로서 ENUM('ENU','JPN','DAN')다음 ORDER Language ASC사용자가 지정한 순서대로 주문합니다.

두 번째는 어딘가에있는 사건, 즉

SELECT * FROM table
ORDER BY CASE Language
    WHEN 'ENU' THEN 3
    WHEN 'JPN' THEN 2
    WHEN 'DAN' THEN 1
    ELSE 0
END DESC, ID ASC

성능면에서 ENUM 방법은 더 빠른 결과를 반환하지만 더 많은 언어를 추가해야하는 경우 더 번거로워집니다. 세 번째 옵션은 언어에 대한 정규화 테이블을 추가하는 것이지만이 경우 과도 할 수 있습니다.


정확히 어디에 입력 ENUM('ENU','JPN','DAN')합니까?
Pathros

1
테이블 정의에서 @pathros를 지정하면 VARCHAR 등 대신 ENUM으로 지정합니다. 내부적으로 MySQL은 ENUM 옵션을 특정 순서로 저장하고 색인을 생성하므로 ENUM 열을 기준으로 주문할 때 특히 내부 색인 대신 해당 내부 색인을 사용합니다. 문자열 값 (CAST ()를 사용하여 VARCHAR로 다시 변환하지 않는 한)
My School Portal의 Simon

END DESC,END CASE DESC,?
Istiaque Ahmed

아니. 모든 것이 CASE필요한 것은 아니며 END CASE상황에 따라 다릅니다. CASEPROCEDURE 내에서는 END CASE( dev.mysql.com/doc/refman/5.5/en/case.html ) 필요 하지만 CASESELECT 내 END CASE에서는 간단히 END( dev.mysql.com/doc/refman/5.7/en/… ) 필요하지 않습니다. 문맥은 제어 흐름 기능입니다.
나의 학교 포털의 Simon

1

Yii2 프레임 워크의 경우 택시는 다음과 같은 방법으로 달성합니다.

Project::find()
->orderBy([new Expression('FIELD(pid_is_t_m,2,0,1)'),'task_last_work'=> SORT_ASC])
->all();
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.