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

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 등이어야합니다.

이것도 가능합니까?



답변

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

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

그러나

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

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


답변

그는 세 개의 값은 경우에, 당신은 사용할 수 있습니다 표현 :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`

)


답변

몇 가지 옵션이 있습니다. 첫 번째는 언어를 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 방법은 더 빠른 결과를 반환하지만 더 많은 언어를 추가해야하는 경우 더 번거로워집니다. 세 번째 옵션은 언어에 대한 정규화 테이블을 추가하는 것이지만이 경우 과도 할 수 있습니다.


답변

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

Project::find()
->orderBy([new Expression('FIELD(pid_is_t_m,2,0,1)'),'task_last_work'=> SORT_ASC])
->all();


답변