Magic: the Gatheringというトレーディング カード ゲーム用のアプリを作成しています。ユーザーが送信したすべてのデッキをチェックし、デッキ内のカードに対するインベントリ内のカードの割合を表示するクエリを作成しました。しかし、私の問題は、データベース上のすべてのデッキに対してこれを行うことです。私がやりたいのは、すでにカードの 50% を持っているデッキだけを返すことです。
クエリは次のとおりです。
SELECT
SUM(t.qty_inv) / t.deck_cards completed,
t.deck_id
FROM (
SELECT
CASE WHEN m.qty_inv IS NULL THEN 0 WHEN m.qty_inv > dc.card_qty THEN dc.card_qty ELSE m.qty_inv END qty_inv,
dc.deck_id,
d.deck_cards
FROM mtgb_test.decks d
INNER JOIN mtgb_test.decks_cards dc ON (d.deck_id = dc.deck_id)
LEFT OUTER JOIN (
SELECT
COUNT(*) qty_inv, item_print_id print_id
FROM mtgb_test.inventories_items
WHERE item_user_id = 1
GROUP BY item_print_id
) m ON (m.print_id = dc.card_print_id)
) t
GROUP BY deck_id
ORDER BY completed DESC;
このクエリの問題は、派生した完了フィールドを where 句で次のように使用できないことです。
WHERE completed > 0.5
変数がこの問題を解決できるかどうかはわかりません。少し試してみましたが、ユーザー定義変数に非常に慣れていないため、うまくいきませんでした。
編集:何人かの善良な人々が、私が HAVING 構文を持っている必要があると答えました。それは正しくて明白な答えです。私はおそらく、あとがきの質問に対する最良の答えを選ぶでしょう。
もう 1 つのことは、データベースに 200,000 のデッキがあり、インベントリに 2,000 のカードがある場合、このクエリでそれらすべてをループして、カードの半分を既に持っているデッキを見つけることで問題ありません。しかし、私の問題は LEFT OUTER JOIN にあります。MySQLが実際に内部でどのように機能するかはわかりませんが、誰かがそれを指摘できるかもしれません. 200,000 のすべてのデッキをループするとき、そこにあるすべてのデッキに対して左の結合を行うでしょうか、それともインベントリ アイテムを 1 回だけクエリするようにこれをキャッシュするのに十分スマートでしょうか?
前もって感謝します、
ラモン