I am trying to write a SQL query that selects the first (based off smallest ID) quest an NPC has available.
If the user already has a quest from that NPC do not return that quest.
Quests
table
id | npc | name
---+---------+------------
1 | NPC-1 | Kill an Ogre
2 | NPC-1 | Kill a Bear
3 | NPC-2 | Kill a Cow
quest_completions table
: if there’s an entry in here it means the quest is in progress unless rewarded is set to true then it is fully done and rewarded and the next quest is available.
quest_name | rewarded | player_id
-------------+-------------+-----------
Kill an Ogre | false | 0
I want to return [NPC-2]
because that is the only NPC with an available quest.
I can show you my SQL query but for some reason it isn’t working. I’m not really sure how to debug it.
SELECT
npc
FROM
(SELECT DISTINCT
ON(npc) quests.npc,
MIN(quests.id),
quests.name
FROM
quests
LEFT JOIN
quest_completions ON quest_completions.quest_name = quests.name
WHERE
(quest_completions.rewarded IS NULL
OR quest_completions.rewarded = false)
AND quest_completions.player_id = 5
GROUP BY
npc, quests.name) a
WHERE
a.name NOT IN (SELECT quest_completions.quest_name
FROM quest_completions
LEFT JOIN quests ON quest_completions.quest_name = quests.name
WHERE rewarded = false);
Edit: I actually created a very detailed fiddle that includes test data and expected output https://www.db-fiddle.com/f/iNs4C1FCitLQqeDzMJg1xn/3
2
Answers
I work with your fiddle. I think it’s working… Take a try.
Here is fiddle:
https://www.db-fiddle.com/f/iNs4C1FCitLQqeDzMJg1xn/7
Ok, after many tests I finally came up with a working solution.
Here is the query:
I had to think of excluding all in progress quest
quests
per NPC then any quest per playerHere is the fiddle: https://www.db-fiddle.com/f/ddf7ZrFhdn9HpKWY4rdXs1/0
I’ve tested all sorts of combinations in my local environment.
Like:
case 1: Returns NPC-2, quest id 3
case 2: Returns NPC-2, quest id 3
case 3: Returns NPC-1, quest id 1
case 4: Returns NPC-1/quest id 2 and NPC-2/quest id 3