【问题标题】:How does sorting on enums actually work?枚举排序实际上是如何工作的?
【发布时间】:2015-04-14 14:20:34
【问题描述】:

在 MySQL 命令行客户端中运行以下查询时,我遇到了一些奇怪的行为:

SELECT favoriteGenre, firstName, lastName 
FROM members 
ORDER BY favoriteGenre, firstName;

我得到以下结果:

favoriteGenre       firstName       lastName
crime               Jane            Field
crime               John            Sparks
horror              Marty           Pareene
thriller            Mary            Newton
romance             Jo              Scrivener
sciFi               Nick            Blakeley
nonFiction          Bill            Swan

但我期待这些结果:

favoriteGenre       firstName       lastName
crime               Jane            Field
crime               John            Sparks
horror              Marty           Pareene
nonFiction          Bill            Swan
romance             Jo              Scrivener
sciFi               Nick            Blakeley
thriller            Mary            Newton

请注意,nonFiction 排在第 7 位,而我预计它会排在第 4 位...

这是用于创建表的 SQL:

USE mydatabase;

CREATE TABLE members (
  id              SMALLINT UNSIGNED NOT NULL AUTO_INCREMENT,
  username        VARCHAR(30) BINARY NOT NULL UNIQUE,
  password        CHAR(41) NOT NULL,
  firstName       VARCHAR(30) NOT NULL,
  lastName        VARCHAR(30) NOT NULL,
  joinDate        DATE NOT NULL,
  gender          ENUM( 'm', 'f' ) NOT NULL,
  favoriteGenre   ENUM( 'crime', 'horror', 'thriller', 'romance', 'sciFi', 'adventure', 'nonFiction' ) NOT NULL,
  emailAddress    VARCHAR(50) NOT NULL UNIQUE,
  otherInterests  TEXT NOT NULL,
  PRIMARY KEY (id)
);

INSERT INTO members VALUES( 1, 'sparky', password('mypass'), 'John', 'Sparks', '2007-11-13', 'm', 'crime', 'jsparks@example.com', 'Football, fishing and gardening' );
INSERT INTO members VALUES( 2, 'mary', password('mypass'), 'Mary', 'Newton', '2007-02-06', 'f', 'thriller', 'mary@example.com', 'Writing, hunting and travel' );
INSERT INTO members VALUES( 3, 'jojo', password('mypass'), 'Jo', 'Scrivener', '2006-09-03', 'f', 'romance', 'jscrivener@example.com', 'Genealogy, writing, painting' );
INSERT INTO members VALUES( 4, 'marty', password('mypass'), 'Marty', 'Pareene', '2007-01-07', 'm', 'horror', 'marty@example.com', 'Guitar playing, rock music, clubbing' );
INSERT INTO members VALUES( 5, 'nickb', password('mypass'), 'Nick', 'Blakeley', '2007-08-19', 'm', 'sciFi', 'nick@example.com', 'Watching movies, cooking, socializing' );
INSERT INTO members VALUES( 6, 'bigbill', password('mypass'), 'Bill', 'Swan', '2007-06-11', 'm', 'nonFiction', 'billswan@example.com', 'Tennis, judo, music' );
INSERT INTO members VALUES( 7, 'janefield', password('mypass'), 'Jane', 'Field', '2006-03-03', 'f', 'crime', 'janefield@example.com', 'Thai cookery, gardening, traveling' );

幕后究竟发生了什么,这种排序是如何进行的?这种行为是否只有 MySQL 独有?

【问题讨论】:

  • 这是一个非常奇怪的结果......
  • 它确实应该按照您的预期进行。大写字母或空格等有什么问题吗?
  • 请发布来自SHOW CREATE TABLE members 的输出。排序取决于表或列的排序规则,favoriteGenre 发生了一些奇怪的事情。
  • 你能用 sqlfiddle 证明这个结果吗?甚至是 phpmyadmin 截图?
  • 这是一个你正在排序的枚举

标签: mysql sql enums sql-order-by


【解决方案1】:

favoriteGenreenum,而不是我们大多数人期望看到的文本字段。

正如您在documentation 中看到的那样,enums 是按其索引排序的,而不是按其文本表示。这使您的查询结果正确。

要按其值对enum 进行排序,您需要使用CAST(col AS CHAR)(感谢McAdam331 添加此内容,另请参阅他的SQLFiddle)。我建议您对您的数据库进行适当的规范化。

【讨论】:

  • 我要补充一点,要按枚举值对枚举进行排序,您需要使用CAST(col AS CHAR),如this fiddle 所示。如果您想将其添加到您的答案中,请继续,我可以删除我的评论。
  • 谢谢@PatrickHofman,解决方案确实有效,但如果可能,请解释在这种情况下标准化将如何提供帮助。
  • 当然。如果您将“标签”(枚举文本)与“id”(枚举索引)分开,您可以根据自己的喜好进行排序。如果需要,还可以在 genre 上添加更多列,但现在无法实现。
  • @McAdam331:谢谢。我添加了它。保留您的评论,让人们知道您是这一切美好的源泉;)。
  • @McAdam331:更新:)
【解决方案2】:

它将首先按第一列对结果进行排序,如果一种类型有多个结果,则在您的情况下是犯罪;它将根据第二个定义的列进行排序。

所以首先它会按最喜欢的流派排序,然后按名字排序

你的情况是 enum ,所以它改变了整个游戏。它只会对其索引进行排序。因此,您会遇到这种奇怪的行为。

希望它能解释

【讨论】:

  • 是的,这对于排序如何工作的更广泛的问题是正确的,但是如果你仔细观察他们返回的结果与他们期望的结果(就像你解释的那样)你会发现那是不会发生。
  • 确实如此。 nonFiction 不应该在最后。这就是问题所在。
  • @McAdam331 您应该早先解释数据类型以了解问题。但是现在我知道问题出在哪里了
  • 当我写我的初始评论时数据类型不存在,OP 之后编辑了这个问题。我为造成的混乱道歉,我自己是在黑暗中。
  • 由于 vishal 更新了他的帖子以使其更加清晰,因此我投了赞成票,因此它不会显示为反对票并混淆未来的读者,因为现在答案是正确的 :)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-21
  • 2011-09-27
  • 2021-12-16
  • 2013-03-14
  • 2021-03-23
  • 2011-02-11
  • 2017-07-31
相关资源
最近更新 更多