5

こんにちは、私は 2 つのテーブルを持っています:user_badgesbadgesテーブル、以下はuser_badgesテーブル データです:

id | user_id | badge_id | points_earned | badges_awarded |
 1    2324        0             5               0

ユーザーが最低限必要なポイント、つまりbadges表の 5 を満たしている場合、SQL は上記を次のように更新します。

id | user_id | badge_id | points_earned | badges_awarded |
 1    2324        1             5               1

今後、同じユーザーに新しいポイントが登録された場合、user_tableバッジは次のように新しい行を追加します。

 id | user_id | badge_id | points_earned | badges_awarded |
  1    2324        1             5               1
  2    2324        0             7               0

上記の問題は解決しました


これはbadges表です:

badge_id | badge_name | required_points
   1           new          5
   2           adv          10

以下は私が必要なものです


問題は、バッジが以前に授与されたかどうかをクエリが認識している必要がある場合、テーブルuser_badgesとテーブルを比較するクエリが必要なことです。badges

これを Zend アプリケーションに使用していますが、この問題の解決策が必要です...

4

3 に答える 3

5

私があなたの質問を正しく理解していれば、まず、バッジがまだ授与されていないユーザーを取得する必要があります。次に、テーブルを使用して、対応する最高の有効なテーブルでテーブルcorrelated subqueryを更新する必要があります。user_badgesbadges_idbadges

UPDATE user_badges a
       INNER JOIN(SELECT DISTINCT user_id, SUM(badges_awarded) AS total_badges_awarded
                  FROM user_badges
                  GROUP BY user_id
                 ) b
             ON a.user_id = b.user_id
                AND b.total_badges_awarded = 0
SET a.badge_id = (@var_badges_awarded_flag:= (IFNULL((
                             SELECT c.badge_id
                             FROM badges c
                             WHERE a.points_earned > c.required_points
                             ORDER BY c.required_points DESC
                             LIMIT 1
                            ), 0))),
    a.badges_awarded = a.badges_awarded + IF(@var_badges_awarded_flag > 0, 1, 0);
于 2012-08-20T07:36:33.793 に答える
0

テーブルで獲得したポイントを追跡する代わりに、テーブル内または別のテーブルuser_badgesのいずれかの場所にそれらを保持します。これにより、簡単にポイントを更新することが容易になります。usersuser_pointsUPDATE ... SET earned_points = earned_points + :points

次に、user_badges表を単純化して次のようにします。

user_id | badge_id

スパンUNIQUEインデックスを使用して、ユーザーが各バッジを複数持つことができないようにします。

最後に、テーブルの更新は、次のuser_badges2 つの手順を使用してバックグラウンド タスク (cron など) として実行できます。

  1. を使用して獲得したバッジを特定しますpoints_earned >= required_points
  2. 新しいバッジをuser_badgesusingに挿入しINSERT IGNORE INTO user_badges ...ます。これにより、新しいバッジのみが追加され、既存のバッジは上書きされません。
于 2012-08-22T06:04:48.757 に答える
0

すべてのユーザーと、各ユーザーが獲得できる次のバッジを取得する SQL ロジックを次に示します。

SELECT *
FROM user_badges
JOIN badges
ON badges.badge_id = (user_badges.badge_id + 1)

次に、各ユーザーを循環して、バッジを PHP で更新する必要があるかどうかを判断できます。

while ($row = mysqli_fetch_assoc($result)) // where result is the result from running the above query
{
    if ($row["points_earned"] >= $row["required_points"]) // enough points for next badge, update badges
    {
        mysqli_query("UPDATE user_badges SET badge_id = badge_id + 1, badges_awarded = badges_awarded + 1 WHERE user_id = ".$row['user_id']);
    }
}

これは、開始するための SQL/PHP コードの例にすぎません。必要な行をクエリし、PHP でチェックし、必要に応じていつでも更新できます。

于 2012-08-14T05:31:32.873 に答える