Извиняюсь за случайный заголовок. Но в основном:
Я разрешаю пользователям проходить квесты, хранящиеся в user_quests
. Квест может попросить пользователя получить несколько предметов, и они хранятся в user_quest_items
.
Состав:
user_quests [ID, идентификатор пользователя, timestamp]
user_quest_items [ID, userquestid, itemid, amount_needed]
Сейчас я пытаюсь выполнить один запрос, чтобы выяснить, есть ли у пользователя необходимое количество предметов в его инвентаре, чтобы я мог просто показать его пользователю. Т.е.
Найти зеленое яблоко [2/4]
Моя система инвентаризации допускает разные экземпляры одного и того же предмета. Структура:
предметы [ID, наименование предмета, описание, редкость]
item_instance [ID, itemid, special_details]
инвентарь [ID, идентификатор пользователя, item_instanceid, количество]
Таким образом, в основном мой запрос должен вычислить, находятся ли предметы, которые запрашивает квест, в пользовательском инвентаре. Мой текущий запрос:
SELECT items.itemname, inventory.quantity, item_instances.ID as instanceid,
item_instances.itemid as instance_itemid, user_quest_items.itemid FROM
user_quest_items
INNER JOIN items ON items.ID = user_quest_items.itemid
INNER JOIN user_quests ON user_quests.ID = user_quest_items.userquestid
LEFT OUTER JOIN inventory ON inventory.userid = user_quests.userid
LEFT OUTER JOIN item_instances ON item_instances.ID = inventory.item_instanceid AND item_instances.itemid = user_quest_items.itemid
WHERE user_quest_items.userquestid = 27
К сожалению, это не работает. Я предполагаю, что это связано с левым внешним объединением инвентаря, но в основном он получает все элементы в пользовательском инвентаре, а не конкретные элементы, заданные user_quest_items.
Это работает, если я изменяю item_instances на INNER JOIN, но возникает проблема, заключающаяся в том, что если у пользователя 0 требуемых элементов, строки не возвращаются, что заставило бы пользователя думать, что его не запрашивают для элементов. В этом случае мне нужно сказать:
Зеленое яблоко [0/4]
Извиняюсь за сложный пост. Существуют и другие причины для создания экземпляра системы инвентаризации (я определенно мог бы сделать это проще, но мне это нужно для других механиков).
Я не уверен, как вы можете включить элементы, которые не существуют. Вы можете, однако, включить идентификатор пользователя, даже если нет элементов. Это можно сделать, запустив цепочку left join
для этого пользователя:
SELECT u.userquestid,
i.itemname, iv.quantity, ii.ID as instanceid,
ii.itemid as instance_itemid, uqi.itemid
FROM (SELECT 27 as userquestid) u LEFT JOIN
user_quest_items uqi
ON u.userquestid = u.userquestid LEFT JOIN
items i
ON i.ID = uqi.itemid LEFT JOIN
user_quests uq
ON uq.ID = uqi.userquestid LEFT JOIN
inventory iv
ON iv.userid = uq.userid LEFT JOIN
item_instances ii
ON ii.ID = iv.item_instanceid AND
ii.itemid = uqi.itemid;