MySQL特殊的ORDER BY

时间:2012-06-05 01:11:07

标签: mysql sql sql-order-by

假设我有下表

name        | genre
---------------------
book 1      | scifi
book 2      | horror
book 3      | scifi
book 4      | romance
book 5      | horror

如何通过SQL中的“流派”对上面的表格进行排序,以获得以下结果。请注意订单。它是H S R,而不是H R S.是否可以在不使用UNION的情况下实现此目的?

name        | genre
------------------------
book 2      | horror
book 5      | horror
book 1      | scifi
book 3      | scifi
book 4      | romance

编辑:只有3种类型。

5 个答案:

答案 0 :(得分:7)

您可以使用字段功能来自定义排序顺序

SELECT * FROM `table` ORDER BY FIELD(`genre`, 'horror', 'scifi', 'horror'), `name`;

答案 1 :(得分:2)

尝试: select * from table order by case when genre="romance" then 1 else 0 end, genre;

答案 2 :(得分:2)

作为上述ENUM答案的替代方案,请添加包含以下内容的类型订单表:

genre_name | sort_order
-----------------------
scifi      | 2
horror     | 1
romance    | 3

然后将您的查询运行为:

SELECT name, genre
FROM books JOIN genres ON books.genre = genres.genre_name
ORDER BY genres.sort_order, books.name;

这样做的另一个好处是,您可以快速轻松地添加类型,而无需更改代码中的硬编码ENUM。但是,无论哪种方式都应该有效。

答案 3 :(得分:0)

  1. 您可以将类型列定义为ENUM类型。如the manual中所述:

      

    ENUM值根据其索引号进行排序,这取决于列规范中列出枚举成员的顺序。例如,'b''a'之前对ENUM('b', 'a')进行排序。空字符串在非空字符串之前排序,NULL值在所有其他枚举值之前排序。

    因此:

    ALTER TABLE my_table MODIFY genre ENUM('horror', 'scifi', 'romance');
    

    您的查询将是:

    SELECT * FROM my_table ORDER BY genre ASC;
    
  2. 或者,您可以存储一个类型表及其在排序中的位置,并将您的查询加入:

    CREATE TABLE genres (genre VARCHAR(10) NOT NULL PRIMARY KEY, position INT);
    INSERT INTO genres VALUES ('horror', 1), ('scifi', 2), ('romance', 3);
    ALTER TABLE my_table ADD FOREIGN KEY (genre) REFERENCES genres (genre);
    

    您的查询将是:

    SELECT   my_table.*
    FROM     my_table JOIN genres USING (genre)
    ORDER BY genres.position ASC;
    

答案 4 :(得分:0)

首先,表格效率非常低(冗余数据) - 所以只需创建一个包含所有类型的新表,并使用外键。

其次,在genres表中添加一个列,并根据排序中的所需位置为每个类型分配一个唯一的编号 - 然后根据该列对该数据进行排序,完成(并且排序顺序可以随时都可以轻松改变。