MySQL:新数据库版本的子查询中的旧 ORDER BY
MySQL: Old ORDER BY in subquery for new DB versions
大家好,希望你们一切都好。
我没有提出很多问题,所以我会尽力做到最好...
我有下面的例子table:
CREATE TABLE `e_rsts_test` (
`id` int(11),
`id_book` int(11),
`lang` varchar(2),
`title` varchar(100)
);
INSERT INTO `e_rsts_test` (`id`, `id_book`, `lang`, `title`) VALUES
(33, 51, 'es', 'Tocar los libros'),
(409, 51, 'en', NULL),
(34, 52, 'de', 'Kaput'),
(35, 53, 'fr', 'Chróniques de la dernière Révolution'),
(36, 54, 'es', 'Veneno para la corona'),
(412, 54, 'en', NULL),
(313, 51, 'it', 'Toccare i libri'),
(314, 53, 'en', 'Cronicles of revolution');
结果如下 table:
id |id_book|lang|title
33 |51 |es |Tocar los libros
409|51 |en |NULL
34 |52 |de |Kaput
35 |53 |fr |Chróniques de la dernière Révolution
36 |54 |es |Veneno para la corona
412|54 |en |NULL
313|51 |it |Toccare i libri
314|53 |en |Cronicles of revolution
我需要从中获取一个新的table,select只获取非NULL标题,如果有多个标题,select优先级之后的记录按语言排序,因此:如果 'es' 语言的标题存在,则为该语言,否则如果 'en' 存在,则为该语言,否则为任何其他语言的标题。在前面的示例中,我需要作为结果获得的 table 将是:
id |id_book|lang|title
33 |51 |es |Tocar los libros
34 |52 |de |Kaput
314|53 |en |Cronicles of revolution
36 |54 |es |Veneno para la corona
我曾经在我的旧 MySQL 数据库中解决这个问题,按以下方式排序子查询:
SELECT id_book_title, title
FROM (SELECT id_book as id_book_title, title
FROM e_rsts_test
ORDER BY ISNULL(title) DESC, (lang = 'es') DESC, (lang = 'en') DESC, id) as c_aux1
GROUP BY id_book_title
但是在新的MySQLDB版本中(开发环境为10.4.13-MariaDB,运行环境为8.0.19),ORDER BY不生效,随机获取了一个NULL结果中的标题 table.
注意:当然,数据库中显示的标题语言最多可达 100 多种,排序标准取决于站点访问者浏览器的语言配置。
注 2:每个 id_book 将至少有一个非 NULL 标题。
在最新的 MySQL 数据库版本中是否有任何解决方案或周转时间来解决这个问题?我搜索了,但找不到任何东西。
感谢您的关注和最诚挚的问候。
在 MySQL 8+ 上,我们可以尝试使用 ROW_NUMBER
和 FIELD
:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY id_book
ORDER BY FIELD(lang, 'en', 'es') DESC) rn
FROM e_rsts_test
WHERE title IS NOT NULL
)
SELECT id, id_book, lang, title
FROM cte
WHERE rn = 1;
大家好,希望你们一切都好。
我没有提出很多问题,所以我会尽力做到最好...
我有下面的例子table:
CREATE TABLE `e_rsts_test` (
`id` int(11),
`id_book` int(11),
`lang` varchar(2),
`title` varchar(100)
);
INSERT INTO `e_rsts_test` (`id`, `id_book`, `lang`, `title`) VALUES
(33, 51, 'es', 'Tocar los libros'),
(409, 51, 'en', NULL),
(34, 52, 'de', 'Kaput'),
(35, 53, 'fr', 'Chróniques de la dernière Révolution'),
(36, 54, 'es', 'Veneno para la corona'),
(412, 54, 'en', NULL),
(313, 51, 'it', 'Toccare i libri'),
(314, 53, 'en', 'Cronicles of revolution');
结果如下 table:
id |id_book|lang|title
33 |51 |es |Tocar los libros
409|51 |en |NULL
34 |52 |de |Kaput
35 |53 |fr |Chróniques de la dernière Révolution
36 |54 |es |Veneno para la corona
412|54 |en |NULL
313|51 |it |Toccare i libri
314|53 |en |Cronicles of revolution
我需要从中获取一个新的table,select只获取非NULL标题,如果有多个标题,select优先级之后的记录按语言排序,因此:如果 'es' 语言的标题存在,则为该语言,否则如果 'en' 存在,则为该语言,否则为任何其他语言的标题。在前面的示例中,我需要作为结果获得的 table 将是:
id |id_book|lang|title
33 |51 |es |Tocar los libros
34 |52 |de |Kaput
314|53 |en |Cronicles of revolution
36 |54 |es |Veneno para la corona
我曾经在我的旧 MySQL 数据库中解决这个问题,按以下方式排序子查询:
SELECT id_book_title, title
FROM (SELECT id_book as id_book_title, title
FROM e_rsts_test
ORDER BY ISNULL(title) DESC, (lang = 'es') DESC, (lang = 'en') DESC, id) as c_aux1
GROUP BY id_book_title
但是在新的MySQLDB版本中(开发环境为10.4.13-MariaDB,运行环境为8.0.19),ORDER BY不生效,随机获取了一个NULL结果中的标题 table.
注意:当然,数据库中显示的标题语言最多可达 100 多种,排序标准取决于站点访问者浏览器的语言配置。 注 2:每个 id_book 将至少有一个非 NULL 标题。
在最新的 MySQL 数据库版本中是否有任何解决方案或周转时间来解决这个问题?我搜索了,但找不到任何东西。
感谢您的关注和最诚挚的问候。
在 MySQL 8+ 上,我们可以尝试使用 ROW_NUMBER
和 FIELD
:
WITH cte AS (
SELECT *, ROW_NUMBER() OVER (PARTITION BY id_book
ORDER BY FIELD(lang, 'en', 'es') DESC) rn
FROM e_rsts_test
WHERE title IS NOT NULL
)
SELECT id, id_book, lang, title
FROM cte
WHERE rn = 1;