MySQL 中的自然排序尝试失败
Failed attempts at natural sort in MySQL
我试图在 MySQL 中实现 natural/alphanumeric 排序,但没有成功。我已经阅读了几篇 Stack 文章和关于我在 google 搜索中找到的主题的各种文章。这是我开始的基本查询:
select VideoTitle, VideoID
from Filters
where VideoSource = 'Netflix'
and IMDBSeries = 'tt0367279'
and PublishDate is not null
ORDER BY VideoTitle
该查询产生此结果集:
Arrested Development Season 1: Ep. 1 Pilot
Arrested Development Season 1: Ep. 10 Pier Pressure
Arrested Development Season 1: Ep. 2 Top Banana
Arrested Development Season 1: Ep. 3 Bringing Up Buster
Arrested Development Season 1: Ep. 4 Key Decisions
Arrested Development Season 1: Ep. 5 Charity Drive
Arrested Development Season 1: Ep. 6 Visiting Ours
Arrested Development Season 1: Ep. 7 In God We Trust
Arrested Development Season 1: Ep. 8 My Mother, the Car
Arrested Development Season 1: Ep. 9 Storming the Castle
请注意,从自然排序的角度来看,此行是乱序的:
Arrested Development Season 1: Ep. 10 Pier Pressure
基于我阅读的 posts/articles,我也尝试了这些方法及其附带的结果集:
select VideoTitle
from Filters
where VideoSource = 'Netflix'
and IMDBSeries = 'tt0367279'
and PublishDate is not null
ORDER BY CAST(VideoTitle AS UNSIGNED), VideoTitle
Arrested Development Season 1: Ep. 1 Pilot
Arrested Development Season 1: Ep. 10 Pier Pressure
Arrested Development Season 1: Ep. 2 Top Banana
Arrested Development Season 1: Ep. 3 Bringing Up Buster
Arrested Development Season 1: Ep. 4 Key Decisions
Arrested Development Season 1: Ep. 5 Charity Drive
Arrested Development Season 1: Ep. 6 Visiting Ours
Arrested Development Season 1: Ep. 7 In God We Trust
Arrested Development Season 1: Ep. 8 My Mother, the Car
Arrested Development Season 1: Ep. 9 Storming the Castle
select VideoTitle
from Filters
where VideoSource = 'Netflix'
and IMDBSeries = 'tt0367279'
and PublishDate is not null
ORDER BY LENGTH(VideoTitle), VideoTitle
Arrested Development Season 1: Ep. 1 Pilot
Arrested Development Season 1: Ep. 2 Top Banana
Arrested Development Season 1: Ep. 4 Key Decisions
Arrested Development Season 1: Ep. 5 Charity Drive
Arrested Development Season 1: Ep. 6 Visiting Ours
Arrested Development Season 1: Ep. 10 Pier Pressure
Arrested Development Season 1: Ep. 7 In God We Trust
Arrested Development Season 1: Ep. 3 Bringing Up Buster
Arrested Development Season 1: Ep. 8 My Mother, the Car
Arrested Development Season 1: Ep. 9 Storming the Castle
select VideoTitle
from Filters
where VideoSource = 'Netflix'
and IMDBSeries = 'tt0367279'
and PublishDate is not null
ORDER BY VideoTitle + 0 ASC
Arrested Development Season 1: Ep. 1 Pilot
Arrested Development Season 1: Ep. 9 Storming the Castle
Arrested Development Season 1: Ep. 8 My Mother, the Car
Arrested Development Season 1: Ep. 7 In God We Trust
Arrested Development Season 1: Ep. 6 Visiting Ours
Arrested Development Season 1: Ep. 5 Charity Drive
Arrested Development Season 1: Ep. 4 Key Decisions
Arrested Development Season 1: Ep. 3 Bringing Up Buster
Arrested Development Season 1: Ep. 2 Top Banana
Arrested Development Season 1: Ep. 10 Pier Pressure
有什么想法吗?
如果你真的想要,你可以逐条排序:
order by substring_index(VideoTitle, ' Season ', 1),
substring_index(VideoTitle, ' Season ', -1) + 0,
substring_index(VideoTitle, ': Ep. ', -1) + 0
这假设字符串 ' Season '
和 : Ep.
在每个标题中只出现一次。
下面的版本应该也很接近,假设季节只有一个数字:
order by substring_index(VideoTitle, ': Ep. ', 1),
substring_index(VideoTitle, ': Ep. ', -1) + 0
最好的解决方案是将节目标题、剧季、剧集编号和剧集标题存储在单独的列中。
在这种情况下,您可以进行一些字符串操作来获得所需内容。
ORDER BY SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(VideoTitle, ': ', -1), ' ', 2), ' ', -1)+0
不过,这是一个非常脆弱的解决方案。
如果创建新列以使您的模型更易于搜索,我会采用更优雅的解决方案,而不是逐个分解字符串。
select VideoTitle
from (select VideoTitle,
VideoTitle REGEXP '.+Ep\. [0-9]{2}.+' vd2dig
from videos
) sub
order by vd2dig, VideoTitle;
这基本上会使 VideoTitle
有两位数字时变为 1
,而当它有一位数字时它将是 0
所以我先按此列排序,然后按自然顺序排序VideoTitle
看到它在这里工作:http://sqlfiddle.com/#!9/6abde/1
我试图在 MySQL 中实现 natural/alphanumeric 排序,但没有成功。我已经阅读了几篇 Stack 文章和关于我在 google 搜索中找到的主题的各种文章。这是我开始的基本查询:
select VideoTitle, VideoID
from Filters
where VideoSource = 'Netflix'
and IMDBSeries = 'tt0367279'
and PublishDate is not null
ORDER BY VideoTitle
该查询产生此结果集:
Arrested Development Season 1: Ep. 1 Pilot Arrested Development Season 1: Ep. 10 Pier Pressure Arrested Development Season 1: Ep. 2 Top Banana Arrested Development Season 1: Ep. 3 Bringing Up Buster Arrested Development Season 1: Ep. 4 Key Decisions Arrested Development Season 1: Ep. 5 Charity Drive Arrested Development Season 1: Ep. 6 Visiting Ours Arrested Development Season 1: Ep. 7 In God We Trust Arrested Development Season 1: Ep. 8 My Mother, the Car Arrested Development Season 1: Ep. 9 Storming the Castle
请注意,从自然排序的角度来看,此行是乱序的:
Arrested Development Season 1: Ep. 10 Pier Pressure
基于我阅读的 posts/articles,我也尝试了这些方法及其附带的结果集:
select VideoTitle
from Filters
where VideoSource = 'Netflix'
and IMDBSeries = 'tt0367279'
and PublishDate is not null
ORDER BY CAST(VideoTitle AS UNSIGNED), VideoTitle
Arrested Development Season 1: Ep. 1 Pilot Arrested Development Season 1: Ep. 10 Pier Pressure Arrested Development Season 1: Ep. 2 Top Banana Arrested Development Season 1: Ep. 3 Bringing Up Buster Arrested Development Season 1: Ep. 4 Key Decisions Arrested Development Season 1: Ep. 5 Charity Drive Arrested Development Season 1: Ep. 6 Visiting Ours Arrested Development Season 1: Ep. 7 In God We Trust Arrested Development Season 1: Ep. 8 My Mother, the Car Arrested Development Season 1: Ep. 9 Storming the Castle
select VideoTitle
from Filters
where VideoSource = 'Netflix'
and IMDBSeries = 'tt0367279'
and PublishDate is not null
ORDER BY LENGTH(VideoTitle), VideoTitle
Arrested Development Season 1: Ep. 1 Pilot Arrested Development Season 1: Ep. 2 Top Banana Arrested Development Season 1: Ep. 4 Key Decisions Arrested Development Season 1: Ep. 5 Charity Drive Arrested Development Season 1: Ep. 6 Visiting Ours Arrested Development Season 1: Ep. 10 Pier Pressure Arrested Development Season 1: Ep. 7 In God We Trust Arrested Development Season 1: Ep. 3 Bringing Up Buster Arrested Development Season 1: Ep. 8 My Mother, the Car Arrested Development Season 1: Ep. 9 Storming the Castle
select VideoTitle
from Filters
where VideoSource = 'Netflix'
and IMDBSeries = 'tt0367279'
and PublishDate is not null
ORDER BY VideoTitle + 0 ASC
Arrested Development Season 1: Ep. 1 Pilot Arrested Development Season 1: Ep. 9 Storming the Castle Arrested Development Season 1: Ep. 8 My Mother, the Car Arrested Development Season 1: Ep. 7 In God We Trust Arrested Development Season 1: Ep. 6 Visiting Ours Arrested Development Season 1: Ep. 5 Charity Drive Arrested Development Season 1: Ep. 4 Key Decisions Arrested Development Season 1: Ep. 3 Bringing Up Buster Arrested Development Season 1: Ep. 2 Top Banana Arrested Development Season 1: Ep. 10 Pier Pressure
有什么想法吗?
如果你真的想要,你可以逐条排序:
order by substring_index(VideoTitle, ' Season ', 1),
substring_index(VideoTitle, ' Season ', -1) + 0,
substring_index(VideoTitle, ': Ep. ', -1) + 0
这假设字符串 ' Season '
和 : Ep.
在每个标题中只出现一次。
下面的版本应该也很接近,假设季节只有一个数字:
order by substring_index(VideoTitle, ': Ep. ', 1),
substring_index(VideoTitle, ': Ep. ', -1) + 0
最好的解决方案是将节目标题、剧季、剧集编号和剧集标题存储在单独的列中。
在这种情况下,您可以进行一些字符串操作来获得所需内容。
ORDER BY SUBSTRING_INDEX(SUBSTRING_INDEX(SUBSTRING_INDEX(VideoTitle, ': ', -1), ' ', 2), ' ', -1)+0
不过,这是一个非常脆弱的解决方案。
如果创建新列以使您的模型更易于搜索,我会采用更优雅的解决方案,而不是逐个分解字符串。
select VideoTitle
from (select VideoTitle,
VideoTitle REGEXP '.+Ep\. [0-9]{2}.+' vd2dig
from videos
) sub
order by vd2dig, VideoTitle;
这基本上会使 VideoTitle
有两位数字时变为 1
,而当它有一位数字时它将是 0
所以我先按此列排序,然后按自然顺序排序VideoTitle
看到它在这里工作:http://sqlfiddle.com/#!9/6abde/1