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

しかし、これは、そのエリアに必要なすべてのアイテムがあるかどうかに関係なく、作成可能なアイテムを示しています. 必要なリソースの 1 つを持っている限り、アイテムが表示されます。

location = $current_location の edible_ground に必要なリソース (およびその量) がすべてある場合にのみ、作成可能なアイテムの名前を表示する方法はありますか?

私が試したことの詳細については:

$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個

魚のスープ、ベリーケーキ、うどんなどには、その地域にいる魚が1匹だけではありません。

誰でもこれを理解するのを手伝ってもらえますか? 私は永遠に感謝しています。私はすでに自分自身を試して数日を過ごしました。お願いします?

誰かが何かを言う前に、私は mysqli を使い始める必要があることを知っています。残念ながら、私がゲームを作り始めたとき (そして数か月前に同時に PHP を学んでいたとき) には、このような機能が存在することさえ知らなかったので、痛々しいほど戻って更新ですべてを変更する必要があります。

4

2 に答える 2

0

s を介してグループ化するレコードの数をチェックするHAVING句が必要ですINNER JOIN

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

編集:

したがって、基本的に次の 2 つの情報を知る必要があります。

  • 必要なリソースの数
  • これらの各リソースには必要な量がありますか

1 つ目は、上記のサブクエリによって解決されます。

そのままのクエリは 2 番目のポイントを満たしていますが、1 つのリソースに対してのみです。

HAVING基本的に、グループ節で特別な魔法を行います。HAVING count(*)X 個のレコードがグループ化されていることを意味します。結合の仕組みにより、リソースごとに item.name が 1 つあります。サブ選択は、そのアイテムに必要な異なるリソースの数、したがってグループ化されたレコードの数を示します。そのサブクエリをグループ化の 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. 現在のアイテムの満たされていない要件を見つけます。(IE. 現場にリソースがない要件を見つける)
  3. 現在の要件に一致し、この場所にあり、十分にある食用資源を見つけます。

現時点では mysql をあまり使用していませんが、これが機能しない場合はお知らせください。

于 2012-09-28T20:37:16.727 に答える