1

I have a SQL result like this:

 name | points
------+-------
 Joe  | 2
 Joe  | 5
 Joe  | 4
 Joe  | 1

Each row represents how many points Joe received per event.

Joe has some basic budget, let's say $100.

What I need to do now is to add a field, which will represent actual budget value, when one point means $10 addition. Something like history of budget growth.

The result should look like this:

 name | points | budget
------+--------+-------
 Joe  | 2      | 120
 Joe  | 5      | 170
 Joe  | 4      | 210
 Joe  | 1      | 220

Usage of a variable seems like the best solution to me, but PostgreSQL is not much friendly with it, so I'm looking for a solution using sumarization of first x rows of the result to get actual points sum since the beginning.

Do you have any idea how to do this without subselecting in each row?

2 Answers 2

1
select name, 
       points,
       100 + sum(points * 10) over (partition by name order by some_timestamp_column) as budget
from the_table
order by some_timestamp_column

You have to have a column that defines a stable sort order over the rows in order to use this.

8
  • Thanks to both of you. This Postgre-specific solution is exactly what I was looking for.
    – mEan
    Commented Jun 13, 2013 at 15:46
  • @mEan: that is not Postgres specific. That is standard ANSI SQL and works in all modern DBMS. (Btw: it's Postgres or PostgreSQL, never Postgre)
    – user330315
    Commented Jun 13, 2013 at 15:47
  • Oh, OK. I probably misunderstood what Samuel Neff wrote, I thought this soulution cannot be used cross-database.
    – mEan
    Commented Jun 13, 2013 at 15:58
  • @a_horse_with_no_name, I don't think this works in MySQL. It definitely doesn't work in SQLite. Commented Sep 29, 2013 at 17:20
  • @SamuelNeff: I never claimed it would work on MySQL or SQLite. I wrote "modern" DBMS - MySQL stopped keeping up with state-of-the-art SQL features somewhere in the 90s (after adding partial support for foreign keys)
    – user330315
    Commented Sep 29, 2013 at 18:28
1

Postgres supports this type of accumulation using an OVER clause, like this:

SELECT name, points, SUM(points * 10) OVER (ORDER BY .. order field ..)
FROM .. table ..
GROUP BY .. unique field ..

A cross-database alternative without a sub-select would be to add this column in your host language (php, java, whatever) and not do it in the database.

1
  • Using window functions is a cross-DBMS solution. They are defined by the SQL standard (back in 2003) and every modern DBMS supports them.
    – user330315
    Commented Jun 13, 2013 at 16:57

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.