SQL-запрос для условного извлечения записей на основе списка значений ключа - PullRequest
0 голосов
/ 10 февраля 2019

У меня есть API, который связывается с базой данных со следующими таблицами:

QUESTS

+----------+------------+
| quest_id | quest_name |
+----------+------------+
|        1 | Q001       |
|        2 | Q002       |
|        3 | Q003       |
|        4 | Q004       |
|        5 | Q005       |
+----------+------------+

НАВЫКИ

+----------+------------+
| skill_id | skill_name |
+----------+------------+
|        1 | S001       |
|        2 | S002       |
|        3 | S003       |
|        4 | S004       |
|        5 | S005       |
+----------+------------+

SKILL_PREREQUISITES

+----------+-----------------------+-------------+
| quest_id | prerequisite_skill_id | skill_value |
+----------+-----------------------+-------------+
|        1 |                     2 |          50 |
|        1 |                     1 |          45 |
|        4 |                     2 |          25 |
|        4 |                     3 |          60 |
|        5 |                     4 |          50 |
+----------+-----------------------+-------------+

Квесты соответствуют уровням в игре, а навыки приобретаются игроками во время игры.Таблица SKILL_PREREQUISITE поддерживает необходимые навыки, необходимые игроку, прежде чем он сможет участвовать в квесте.

Задача

Конечная точка API-интерфейсасписок навыков, которыми обладает игрок, а также уровень навыка (skill_value) соответствующего навыка, например:

[
{
  "key": 1, //skill ID
  "value": 45 //skill value
},
{
  "key": 2,
  "value": 60
}
...
]

Теперь мой вариант использования , чтобы использовать эти значения и запроситьбаза данных для получения списка квестов, в которых игрок имеет право участвовать на основе skill_id, а также skill_value

Пример

Предположим, API получаетследующее отображение значения навыка-навыка:

skill-value map: [{1,50}, {2,60}, {4,50}]

На основании этого игрок с вышеуказанным набором навыков может участвовать в квестах 1 и 5, но не в 4, поскольку 4 требует навыка 3 с 60 очками.

Попытка найти решение

Мне удалось написать запрос (благодаря предыдущему вопросу, который я разместил!), Чтобы определить задания, соответствующие идентификаторам навыков, но японятия не имею как отфильтроватьдальше в запросе, основанном на значении навыка.

Мне интересно, возможно ли это на этом этапе и нужно ли мне выполнять дополнительную обработку на сервере, чтобы получить требуемый результат.

Fiddle для моей попытки найти решение: https://www.db -fiddle.com / ж / s2umHS1wz3Q8ibwUhKDas6 / 1

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

Сложность заключается в том, что вам нужно передать эти значения, полученные из ответа API, на ваш оператор SQL в качестве входных данных и сгенерировать выходные данные, динамически создавая отсутствие сравнений на основе входных данных.

Теперь, если бы яВы знакомы с вашей серверной платформой, чем я бы дал более подходящее решение, но, поскольку я не знаком с Node.js, мое решение будет включать только необходимые операторы SQL и оставшуюся часть, необходимую для самостоятельной работы.

Первое, что вам нужно сделать, - это проанализировать этот ответ API и сохранить эти значения в структуре данных.

Теперь создайте Temporary table из вашего Node.js кода и сохраните эти входные значения вэта таблица.

  CREATE TEMPORARY TABLE Input (id INT, value INT);

Добавьте данные из этой структуры данных в эту таблицу.

Теперь выполните следующий запрос, и вы получите то, что хотите:

SELECT skp.quest_id
FROM SKILL_PREREQUISITES skp 
GROUP BY quest_id
HAVING COUNT(skp.quest_id) =
                     ( SELECT COUNT(quest_id)
                       FROM Input i
                       JOIN SKILL_PREREQUISITES sp
                       ON sp.prerequisite_skill_id = i.id
                       AND sp.skill_value <= i.value
                       WHERE skp.quest_id = sp.quest_id
                      )

Демонстрационная скрипка

0 голосов
/ 10 февраля 2019

Вы можете сформулировать запрос, сравнив оба навыка и значение:

SELECT q.quest_id
FROM QUESTS q LEFT JOIN
     SKILL_PREREQUISITES p
     ON p.quest_id = q.quest_id
GROUP BY q.quest_id
HAVING SUM( p.prerequisite_skill_id = 1 and 50 >= p.skill_value) > 0 AND
       SUM( p.prerequisite_skill_id = 2 and 60 >= p.skill_value) > 0 AND
       SUM( p.prerequisite_skill_id = 4 and 50 >= p.skill_value) > 0 ;

Поскольку вам нужны квесты, которые имеют предварительные условия, LEFT JOIN не требуется.Фактически, JOIN вообще не требуется:

SELECT p.quest_id
FROM SKILL_PREREQUISITES p
WHERE p.prerequisite_skill_id IN (1, 2, 4)
GROUP BY p.quest_id
HAVING SUM( p.prerequisite_skill_id = 1 and 50 >= p.skill_value) > 0 AND
       SUM( p.prerequisite_skill_id = 2 and 60 >= p.skill_value) > 0 AND
       SUM( p.prerequisite_skill_id = 4 and 50 >= p.skill_value) > 0 ;

Фильтрация перед GROUP BY является необязательной, но она может улучшить производительность.

РЕДАКТИРОВАТЬ:

Я думаю, что ответил на неправильный вопрос выше.Я думаю, что вы хотите все навыки, которые доступны с учетом предварительных условий пользователя.Это было бы:

SELECT q.quest_id
FROM QUESTS q LEFT JOIN
     SKILL_PREREQUISITES p
     ON p.quest_id = q.quest_id
GROUP BY q.quest_id
HAVING COALESCE(SUM( (p.prerequisite_skill_id = 1 and 50 >= p.skill_value) +
                     (p.prerequisite_skill_id = 2 and 60 >= p.skill_value) +
                     (p.prerequisite_skill_id = 4 and 50 >= p.skill_value)
                   )) = COUNT(p.prerequisite_skill_id);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...