0

I have a large stats table in a Postgres DB where the schema looks like this:

player_id: integer,
region: string,
position: string,
league: string,
stats: json

I used this blog post to build the following query to find the average of a given attribute in the stats json object (using as an example the 'hits' stat):

attributes = {region: 'x', position: 'y', league: 'z'}
Stat.where(attributes).average("cast(payload ->> 'hits' as integer)").to_f

That works well and it's fast. Some of the stats, however, need to be built as a function of time the player was in game. Given a stats object with the following format:

{
  "kills":10
  "time_played":120 # seconds
}

I would want to get a value of 5 kills per minute (10 / (120/60)) assuming that was the only stat found (it would be much more, that's why I'm doing average, but for the sake of a simple example...)

Here I'm quite stuck. I know that sql has no trouble dividing things, but throwing in the JSON has me confused. I've tried this:

Stat.where(attributes).average("cast(payload ->> 'kills' as integer) / (cast(payload ->> 'time_played' as integer) / 60)").to_f

it returns 0 - and I'm not really sure how to debug this statement. Any ideas?

solution:

this is what ended up working, with help from EgonWilzer:

def query_for(stat, per_minute: false)
  base = "cast(payload ->> '#{stat}' as float)"

  return base unless per_minute
  base + " / (cast(payload ->> 'time_played' as float) / 60)"
end
3
  • The problem is probably the division integer / integer, which will always return 0 if the second one is bigger. Maybe you could try it with as real instead of as integer? Commented Sep 1, 2015 at 14:15
  • nice idea, @EgonWilzer, but doesn't change output. Commented Sep 1, 2015 at 14:40
  • i take it back - i had a mistake (wasn't dividing the time_played bit by 60!) and that does seem to work - if you add it as an answer i'll happily accept it. cheers Commented Sep 1, 2015 at 14:48

1 Answer 1

1

The problem is the division integer / integer, which will always return 0 if the second one is bigger.

You could probably get the expected result with as real instead of as integer.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.