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.