РЕДАКТИРОВАТЬ ОБНОВЛЕНИЕ: Оказывается, у меня есть версия 5.7, поэтому функции окна не вариант для поиска решения.
SHOW VARIABLES LIKE 'version';
+---------------+------------+
| Variable_name | Value |
+---------------+------------+
| version | 5.7.21-log |
+---------------+------------+
Описание проблемы: у меня есть таблица троичных отношений между предложениями, навыками и профилями. Эти троичные отношения имеют атрибут ранжирования.
У меня есть таблица навыков, где я могу увидеть название навыка. До сих пор мне приходилось делать два запроса:
1) Дайте мне 10 лучших навыков в профиле:
SELECT DISTINCT ternary.id_skill, skill.name_skill, ranking_skill
FROM ternary
INNER JOIN skill ON skill.id_skill=ternary.id_skill
WHERE ternary.id_perfil= #IntNumber#
GROUP BY ternary.id_skill
ORDER BY ternary.ranking_skill DESC
LIMIT 10;
2) Для получения списка навыков идентификации, сообщите мне, если они появляются в каком-либо профиле, и сколько раз они появляются.
SELECT DISTINCT ternary.id_profile, nombre_profile, COUNT(DISTINCT ternary.id_skill) AS matching
FROM ternary
INNER JOIN profile ON ternary.id_profile=profile.id_profile
WHERE ternary.id_skill= '858534430'
OR ternary.id_skill= '3213227'
OR ternary.id_skill= '3254818'
GROUP BY(ternary.id_profile)
ORDER BY matching DESC;
В этом последнем запросе была обнаружена проблема: он «ищет» навык, появляющийся в любой точке профиля. Поскольку профиль может иметь тысячи навыков, он может вводить в заблуждение из-за того, что мы хотим достичь Теперь мне нужно «искать» только в том случае, если это один из 10 лучших навыков ЛЮБОГО профиля. Но только в топ-10.
До сих пор, в основном, я пытался смешать оба запроса, но без особого успеха, потому что кажется, что я не могу сделать разделение на два столбца, и даже если я использую только один, я получаю You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '(PARTITION BY
:
SELECT *
FROM
(
SELECT DISTINCT ternary.id_skill,
skill.name_skill,
ternary.ranking_skill,
ternary.id_profile,
ROW_NUMBER() OVER(PARTITION BY id_profile, id_skill ORDER BY ternary.ranking_skill DESC) rn
FROM ternary
INNER JOIN skill ON skill.id_skill=ternary.id_skill
)
WHERE rn < 11;
Я узнал, что эту операцию можно назвать групповым максимумом, и я видел несколько ответов, ищущих это. Мне не удалось воспроизвести ни одну из них, и она мне нужна специально для mysql Ver 14.14 Distrib 5.5.60, for Linux (x86_64) using readline 5.
, если это поможет (я пробовал ответы, которые идеально подходили для некоторых других, похожих баз данных, но не работали бы в mysql).
Определение таблиц:
CREATE TABLE `ternary` (
`id_offer` varchar(200) NOT NULL,
`id_skill` varchar(200) NOT NULL,
`id_profile` varchar(200) NOT NULL,
`ranking_skill` double NOT NULL,
PRIMARY KEY (`id_offer`,`id_skill`,`id_profile`),
KEY `id_skill` (`id_skill`),
KEY `id_profile` (`id_profile`),
CONSTRAINT `ternary_ibfk_1` FOREIGN KEY (`id_offer`) REFERENCES `offer` (`id_offer`),
CONSTRAINT `ternary_ibfk_2` FOREIGN KEY (`id_skill`) REFERENCES `skill` (`id_skill`),
CONSTRAINT `ternary_ibfk_3` FOREIGN KEY (`id_profile`) REFERENCES `profile` (`id_profile`)
)
CREATE TABLE `skill` (
`id_skill` varchar(200) NOT NULL,
`name_skill` varchar(200) DEFAULT NULL,
`date` date DEFAULT NULL,
PRIMARY KEY (`id_skill`)
)
Результаты выполнения
select * from ternay limit 10;
+------------+------------+-----------+----------------------+
| id_oferta | id_skill | id_perfil | ranking_skill |
+------------+------------+-----------+----------------------+
| 1004 | 107 | 679681082 | 0 |
| 1004 | 115 | 679681082 | 0.10846866454897801 |
| 1004 | 117 | 679681082 | 0.038003619695992294 |
| 1004 | 129 | 679681082 | 0.04987975085098989 |
| 1004 | 147 | 679681082 | 0.02771097269499438 |
| 1004 | 299 | 679681082 | 0.0522549770819894 |
| 1004 | 321 | 679681082 | 0.11955305362697576 |
| 1004 | 417 | 679681082 | 0.11321911701097703 |
| 1004 | 964 | 679681082 | 0.015043099462996949 |
| 1004 | 967 | 679681082 | 0.05304671915898924 |
+------------+------------+-----------+----------------------+
Результат запроса 1) описать выше, который дает мне топ-10 для одного профиля
+------------+--------------+---------------------+
| id_skill | name_skill | ranking_skill |
+------------+--------------+---------------------+
| 109 | scala | 0.3089840175329823 |
| 122 | hadoop | 0.24164146109602963 |
| 9731 | python | 0.21470443852124863 |
| 325 | java | 0.18776741594646754 |
| 114 | sql | 0.14736188208429596 |
| 101 | kafka | 0.13389337079690544 |
| 301 | bbdd | 0.13389337079690544 |
| 927 | agile | 0.13389337079690544 |
| 320 | hive | 0.1204248595095149 |
| 109 | spark | 0.1204248595095149 |
+------------+--------------+---------------------+