2017-01-23 18 views
0

私は、コメントを書く(+5ポイント)、画像をアップロードする(+10ポイント)などの特定のアクションに対して「ユーザーポイント」を得ることができるユーザーコミュニティを持っています。 Tシャツ(-100ポイント)のようなものを「購入する」ために慣れる。MySQLテーブル - 過去12ヶ月間のポイントを計算する

  • ID(int型、PK)(ユーザテーブルにINT、FK)
  • USER_ID(アクションテーブルにINT、FK)
  • action_id
  • ポイント:すべてのアクションは、MySQLのテーブルuserpoints_logに記録されています(INT、+5または-100などポイント自体)
  • のcreated_at(日付)現在

、私はすることにより、ユーザ毎userpointsを計算します(USER_IDで識別される)このテーブルのすべてのポイントログの:全て(正)ポイントは12ヶ月間のみ有効でなければなりませんので

SELECT SUM(points) AS 'result' FROM userpoints_log 
WHERE user_id = X 
GROUP BY user_id 

は、今私は、この計算を変更する必要があります。私はまず、次のようにします:

SELECT SUM(points) AS 'result' FROM userpoints_log 
WHERE user_id = X AND created_at > DATE(NOW()-INTERVAL 1 YEAR) 
GROUP BY user_id 

しかし、それは私に間違った結果をもたらします。たとえば、次のデータセットのために:私は2017年4月15日に上記のクエリを実行したい場合

created_at |points 
------------------ 
2016-04-01 | +1000 
2016-05-01 | -500 
2016-06-01 | +500 

、私は結果として正しくない0ポイント(-500 + 500)、になるだろう、ユーザーには500ポイントが必要です。

500ポイントが正しい結果です。ユーザーがポイントを使用するとき(-500)、彼はまず「最も古い」ポイントを使用し、将来のポイントを使用できないためです。私たちが2016年4月1日から+1000ポイントを除外したと仮定すると、すでに500ポイントが使用されています(2016-05-01で-500)。

正しい値を得るために使用できる数式やクエリのアイデアはありますか?

+0

あなたは 'GROUP BY'を見ることを試みましたか? あなたはGROUP BY user_idのような何かが間違っていると思います。グループに入れたいものは何でもいいです。 –

+1

その例の出力が0ではなく500である理由についていくつかの詳細を教えてください。 –

+0

@IkeWalker:質問を更新しました。要約:500ポイントが正しい結果です。ユーザーがポイントを使用するとき(-500)、まず「最も古い」ポイントを使用し、将来のポイントを使用できないためです。私たちが2016年4月1日から+1000ポイントを除外したと仮定すると、すでに500ポイントが使用されています(2016-05-01で-500)。 – bernhardh

答えて

0
SELECT SUM(case when points < 0 and create_at < (
    select min(create_at) from userpoints_log where user_id = X 
    and created_at > DATE(NOW()-INTERVAL 1 YEAR) and points > 0 
) then 0 else points) AS 'result' 
FROM userpoints_log 
WHERE user_id = X AND created_at > DATE(NOW()-INTERVAL 1 YEAR) 

psedoコードですが、そのロジックを使用できます。
1.最初の+ポイント日付を見つけよう
2.最初に獲得した前の変更点データ

関連する問題