Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to define a custom ORDER BY order in mySQL

Tags:

mysql

People also ask

How do I create a custom order in SQL?

By default SQL ORDER BY sort, the column in ascending order but when the descending order is needed ORDER BY DESC can be used. In case when we need a custom sort then we need to use a CASE statement where we have to mention the priorities to get the column sorted.

How do you specify an order in SQL?

The SQL ORDER BY Keyword The ORDER BY keyword is used to sort the result-set in ascending or descending order. The ORDER BY keyword sorts the records in ascending order by default. To sort the records in descending order, use the DESC keyword.

How do I create a database order in MySQL?

You need to use backtick around the table name order. Backtick allow a user to consider the keyword as table or column name. Insert some records in the table using insert command. Display all records from the table using select statement.

How do I change the order of rows in MySQL?

An "ALTER TABLE ORDER BY" statement exist in the syntaxes accepted by MySQL. According to the documentation, this syntax: - only accept *one* column, as in "ALTER TABLE t ORDER BY col;" - is used to reorder physically the rows in a table, for optimizations.


MySQL has a handy function called FIELD() which is excellent for tasks like this.

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

Note however, that

  1. It makes your SQL less portable, as other DBMSs might not have such function

  2. When your list of languages (or other values to sort by) gets much longer, it's better to have a separate table with sortorder column for them, and join it to your queries for ordering.


If those are the only three values, then you can use a CASE expression:

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

(If there could be other values, then you may want to add some extra logic to keep the ordering consistent; for example, you might add ELSE 4 to that CASE expression, and then order by Language itself as the third ordering criterion:

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

)


You have a couple of options offhand, the first is to change Language to be ENUM (assuming this is possible, and you only expect a few variations)

If you specify it as ENUM('ENU','JPN','DAN') then ORDER Language ASC will order in the order you specify.

The second will involve a case somewhere, i.e.

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

Performance-wise the ENUM method will return faster results, but be more hassle if you need to add more languages. A third option would be to add a normalisation table for the Languages however that may be overkill in this instance.


For Yii2 framework we can achieve by following way

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