MySQL:按第二列排序——如果不是null——同时保持第一列的顺序



本质上,我想按"标题"排序,同时将电影与相同的非null "series_id"分组。按这个顺序排列。series_id为NULL的标题应该只按标题排序,而非NULL的series_id应该按"series_order"排序。并根据"系列"标题"在结果中列出。在原始列内排序。我更愿意在查询中实现这一点,而不是加载整个数据库并从那里排序。

What I have try (MySQL 5.7.17):

ORDER BY title, series_id

SELECT * FROM media
ORDER BY title, series_id, series_order
LIMIT 0, 30

不考虑系列中字母顺序不同的标题(参见下面的示例)。

ORDER BY CASE使用CONCAT按'series'排序。'title' + 'media'.'series_order'

SELECT * FROM media
ORDER BY CASE
WHEN series_id IS NULL THEN title
ELSE CONCAT((SELECT title FROM series WHERE id = media.series_id), series_order)
END
LIMIT 0, 30

结果在SQL Fiddle中是正确排序的,但在开发服务器上不是。公平地说,这仍然不是"系列"所期望的结果。"title"可能与原电影标题不同。

LEFT JOIN包含'series'表进行排序,使用相同的思想

SELECT media.*, series.title, series.id FROM media
LEFT JOIN series ON media.series_id = series.id
LIMIT 0, 30

这也没有正确排序数据。

示例数据:

<表类>标题series_idseries_ordertbody><<tr>88分钟空空自由生活或死亡困难1000944第三岩石从太阳10000022枪空空舍命1000941尸空空一天努力死1000945第三岩石从太阳1000001

基于所需的卷积来实现所需的排序,如果这是我的应用程序,我可能会创建一个包含"基标题"的新列。对于序列并在插入期间填充该值,然后您可以对其进行排序,而无需任何巫术或眼睛疲劳。

在没有修改表结构的情况下,我设法将使用ROW_NUMBER()PARTITION(MySQL8.0 Demo)的解决方案降级为一对嵌套子查询-这不是我认为美丽的。

SQL(演示)

SELECT m2.title grouping_title, m1.title, COALESCE(m2.title, m1.title), m1.series_order
FROM media m1
LEFT JOIN (
SELECT series_id, title
FROM media m3
WHERE series_order = (SELECT MIN(series_order) FROM media WHERE series_id = m3.series_id)
) m2 ON m1.series_id = m2.series_id
ORDER BY COALESCE(m2.title, m1.title), m1.series_order

您可以根据需要修改外部SELECT,但我只是想展示COALESCE()函数生成的内容。实际上,我将媒体表连接到它本身,以便我可以获得给定series_id的最低series_order值。那一行中的title表示"基本标题"。在排序算法的第一条规则中使用——除非是NULL,在这种情况下,我们只使用父查询中的title

对于您的应用程序输出,您将希望使用m1.titlem1.series_order

使用CASE表达式检查seris_order值是否为null,如果为null则只取titlw,否则将title与series_order连接。

查询

Select case when series_order is null then title else concat(title, ' : Season ', series_order) end as title
From table_name
Order by 1;

最新更新