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
그러나
-
다른 DBMS에는 이러한 기능이 없을 수 있으므로 SQL의 이식성이 떨어집니다.
-
언어 목록 (또는 정렬 할 다른 값)이 훨씬 길어지면 정렬 순서 열이 포함 된 별도의 테이블을 만들고 쿼리를 위해 정렬하는 것이 좋습니다.
답변
그는 세 개의 값은 경우에, 당신은 사용할 수 있습니다 표현 :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();