4

假设我有下表

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

如何按“流派”对上表进行排序SQL以获得以下结果。请注意顺序。它是 HSR,而不是 HR S。是否可以在不使用的情况下实现这一目标UNION

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

编辑:只有 3 种流派。

4

5 回答 5

7

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

SELECT * FROM `table` ORDER BY FIELD(`genre`, 'horror', 'scifi', 'horror'), `name`;
于 2012-06-05T01:16:06.243 回答
2

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

于 2012-06-05T01:15:34.727 回答
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。不过,无论哪种方式都应该有效。

于 2012-06-05T01:17:24.743 回答
0
  1. 您可以将您的流派列定义为一种ENUM类型。如手册所述:

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

    所以:

    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;
    
于 2012-06-05T01:14:41.000 回答
0

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

其次,在流派表中添加一列,并根据排序中所需的位置为每个流派分配一个唯一编号 - 然后从现在开始按该列对数据进行排序,完成(并且可以轻松更改排序顺序任何时候)。

于 2012-06-05T01:18:11.813 回答