假设我有下表
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种类型。
答案 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)
您可以将类型列定义为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;
或者,您可以存储一个类型表及其在排序中的位置,并将您的查询加入:
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表中添加一个列,并根据排序中的所需位置为每个类型分配一个唯一的编号 - 然后根据该列对该数据进行排序,完成(并且排序顺序可以随时都可以轻松改变。