MySQL групповой максимум

0

EDIT UPDATE: Оказывается, у меня есть версия 5.7, поэтому функции Window не являются опцией для поиска решения.

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 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 |
+------------+--------------+---------------------+
  • 2
    Оконные функции доступны из MySQL 8.0
  • 0
    @LukaszSzozda Я вижу, так что OVER (Partition BY) должно быть возможно, если это необходимо для решения. Спасибо!
Показать ещё 9 комментариев
Теги:
groupwise-maximum

1 ответ

1

Вот пример, по Row_number() вы создаете Row_number() с помощью функций Window, вы можете попытаться написать подзапрос в предложении select.

  • PARTITION BY Условие записи столбца в подзапросе where where.
  • count(*) подзапроса count(*) чтобы сделать Row_number

выглядят так.

SELECT * FROM 
(
SELECT *,(
     select (count(*) + 1) rn
     from ternary 
     where 
        t.id_profile = id_profile and 
        t.id_profile = id_profile and 
        ranking_skill > t.ranking_skill
   ) rn
  FROM ternary t
) t
WHERE rn < 11
order by rn 

sqlfiddle: http://sqlfiddle.com/#!9/7ee529/9

этот запрос может быть работой, которую вы можете попробовать.

SELECT *
FROM
(
  SELECT DISTINCT t.id_skill,
                   skill.name_skill,
                   t.ranking_skill,
                   t.id_profile,
                   (
                     select (count(*) + 1) rn
                     from ternary 
                     where t.id_profile = id_profile and t.id_profile = id_profile
                     and ranking_skill > t.ranking_skill
                   ) rn
   FROM ternary t
   INNER JOIN skill ON skill.id_skill=t.id_skill;
)
WHERE rn < 11;

Ещё вопросы

Сообщество Overcoder
Наверх
Меню