0

这是我的问题:我正在为游戏制作制作系统,并且我的数据库中已经充满了制作物品所需的资源信息。

这是我的相关表格的样子:

table #edible_resources
(edible_resource_id, edible_resource_name, hunger_points, degeneration_id)

table #edible_ground
(id, resource, amount, location)

table #req_crafting_edible
(req_crafting_edible_id, edible_resource_id, req_resource_amount, created_item_id)

table #items
(item_id, item_name, degeneration_id, is_grounded, is_stackable, can_equip, can_edit)

我想要做的是 - 仅 - 当且仅当 - 所有需要的资源(及其所需数量)都在角色位置的地面上时,才回显可制作物品的名称。

我有一个接近的查询:

SELECT items.item_name, items.item_id FROM items
INNER JOIN req_crafting_edible
ON req_crafting_edible.created_item_id = items.item_id
INNER JOIN edible_ground
ON edible_ground.resource = req_crafting_edible.edible_resource_id
AND edible_ground.amount >= req_crafting_edible.req_resource_amount
WHERE edible_ground.location = $current_location
GROUP BY items.item_name
ORDER BY items.item_name

但这向我展示了可制作的物品,无论我是否在该地区拥有所有必需的物品。只要我拥有他们所需的资源之一,它就会向我展示项目。

只有当我在 edible_ground where location = $current_location 中拥有所有必需的资源(及其数量)时,有没有办法只显示可制作物品的名称?

有关我尝试过的更多信息:

$get_char = mysql_query("SELECT current_char FROM accounts WHERE account_id ='".$_SESSION['user_id']."'");
$current_char = mysql_result($get_char, 0, 'current_char');

$get_loc = mysql_query("SELECT current_location FROM characters WHERE character_id = $current_char");
$current_location = mysql_result($get_loc, 0, 'current_location');

//---------------------------------------------------------------COOKED FOOD
$get_food = mysql_query("SELECT items.item_name, items.item_id FROM items
INNER JOIN req_crafting_edible
ON req_crafting_edible.created_item_id = items.item_id
INNER JOIN edible_ground
ON edible_ground.resource = req_crafting_edible.edible_resource_id
AND edible_ground.amount >= req_crafting_edible.req_resource_amount
WHERE edible_ground.location = $current_location
GROUP BY items.item_name
ORDER BY items.item_name");
while ($food = mysql_fetch_array($get_food)){
  echo $food['item_name'].'<br>';
}

这将返回:

  • 烤鱼
  • 烧焦的鱼
  • 鱼汤
  • 釉面浆果
  • 蛋糕
  • 烤鱼
  • 生鱼片
  • 海鲜汤
  • 寿司
  • 乌冬面

在地上:

  • 1 条鱼
  • 1个蜂蜜

尽管鱼汤、浆果蛋糕、乌冬面等需要的不仅仅是该地区的一条鱼。

谁能帮我解决这个问题?我将永远感激;我已经花了几天时间尝试自己。请?

在任何人说什么之前,我知道我需要开始使用 mysqli;不幸的是,当我开始制作游戏时(几个月前同时学习 PHP),我什至没有意识到它的存在,所以我不得不痛苦地回去并在更新中进行全部更改。

4

2 回答 2

0

您需要一个HAVING子句来检查您通过INNER JOINs 分组的记录数。

HAVING count(*) = (
  SELECT count(*)
    FROM req_crafting_edible
    WHERE req_crafting_edible.created_item_id = items.item_id
)

编辑:

所以基本上你需要知道两条信息:

  • 需要多少不同的资源
  • 这些资源中的每一个是否都有所需的数量

第一个由上面的子查询解决。

您的查询原样满足第二点,但仅适用于 1 个资源。

HAVING基本上对您的 group 条款有一些特殊的魔力。HAVING count(*)表示有 X 条记录被组合在一起。由于连接的工作方式,每个资源都有 1 个 item.name。子选择为您提供了该项目需要多少不同资源以及分组记录的计数。将该子查询与分组的 count(*) 进行比较可确保您拥有所有需要的资源。

这是最终查询,修改上面的代码:

SELECT items.item_name, items.item_id
  FROM items
    INNER JOIN req_crafting_edible
      ON req_crafting_edible.created_item_id = items.item_id
    INNER JOIN edible_ground
      ON edible_ground.resource = req_crafting_edible.edible_resource_id
        AND edible_ground.amount >= req_crafting_edible.req_resource_amount
  WHERE edible_ground.location = $current_location
  GROUP BY items.item_name
  HAVING count(*) = (
    SELECT count(*)
      FROM req_crafting_edible
      WHERE req_crafting_edible.created_item_id = items.item_id
  )
  ORDER BY items.item_name
于 2012-09-28T20:15:39.073 回答
0

您实际上只需要 items 表中的数据,对吗?如果是这样,我将转向使用现有模型:

SELECT I.item_name, I.item_id FROM items I
WHERE NOT EXISTS 
  (SELECT created_item_id
   FROM req_crafting_edible R
   WHERE R.created_item_id = I.item_id
     AND NOT EXISTS
       (SELECT G.resource
        FROM edible_ground G
        WHERE G.resource = R.edible_resource_id
          AND edible_ground.location = $current_location
          AND G.amount >= R.req_resource_amount))
ORDER BY I.item_name

我没有你的数据库来检查这个,但逻辑是这样的:

  1. 找出没有任何不满足要求的项目。
  2. 查找当前项目未满足的要求。(即,查找没有实地资源的需求)
  3. 找到符合当前要求的可食用资源,在这个位置,并且有足够的资源。

我目前在 mysql 中工作不多,但如果这不起作用,请告诉我。

于 2012-09-28T20:37:16.727 回答