我有一个API,该API与具有以下表格的数据库通信:
问题
+----------+------------+
| 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
和{{ 1}}
示例
假设该API收到以下技能技能值映射:
skill_value
基于此,具有上述技能的玩家可以参加任务1和5,但不能参加任务4,因为4要求技能3得60分。
尝试解决方案
我已经设法编写了一个查询(由于我之前发布了一个问题!),以标识与技能ID对应的任务,但是我不知道如何根据技能值在查询中进一步过滤此查询。
我想知道这是否可能,并且是否可能需要在服务器上进行进一步处理才能获得所需的结果。
为我的解决方案做准备:https://www.db-fiddle.com/f/s2umHS1wz3Q8ibwUhKDas6/1
答案 0 :(得分:2)
这里的挑战是,您需要将从API响应中检索到的这些值作为输入传递给SQL语句,并通过基于输入动态创建不进行比较的方式来生成输出。
现在,如果我比后端平台更熟悉,我会提供更多合适的解决方案,但是由于我不了解Node.js,我的解决方案将仅包含必需的SQL语句和其余部分你需要DIY。
您需要做的第一件事是解析此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
)
答案 1 :(得分:1)
您可以通过比较技能和值来用词组查询:
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);