Take the 2-minute tour ×
Database Administrators Stack Exchange is a question and answer site for database professionals who wish to improve their database skills and learn from others in the community. It's 100% free, no registration required.

I'm trying to use postgres' RANGE clause within a window function to dynamically set the window to the past 4 weeks not including the current date. Here is my attempt at it:

SELECT date("aa0"."created_at") AS "Day of Created At",
       "aa0"."user_id" AS "User Id",
       count (*) activities_today,
       count(*) over (PARTITION BY "aa0"."user_id"
                      ORDER BY date("aa0"."created_at") ASC
                      RANGE BETWEEN date("aa0"."created_at" - interval '4 weeks')
                                    AND 
                                    date("aa0"."created_at" - interval '1 day')
                ) active_days_past_4_weeks
FROM "public"."activity_activity" AS "aa0"
GROUP BY date("aa0"."created_at"), "aa0"."user_id" 
ORDER BY "Day of Created At" ASC LIMIT 1000;

However, I get the following error:

ERROR: syntax error at or near ")" Position: 459

If I use ROWS instead of RANGE it works but this is not the correct logic since it's not guaranteed that there will be a row for every day:

SELECT date("aa0"."created_at") AS "Day of Created At",
       "aa0"."user_id" AS "User Id",
       count(*) activities_today,
       count(*) over (PARTITION BY "aa0"."user_id"
                      ORDER BY date("aa0"."created_at") ASC
                      ROWS BETWEEN 28 PRECEEDING AND 1 PRECEEDING
                ) active_days_past_4_weeks
FROM "public"."activity_activity" AS "aa0"
GROUP BY date("aa0"."created_at"), "aa0"."user_id" 
ORDER BY "Day of Created At" ASC LIMIT 1000;

Schema:

CREATE TABLE activity_activity (
  user_id int,
  created_at timestamp
)

Version:

select version()

PostgreSQL 9.3.4 on x86_64-unknown-linux-gnu, compiled by gcc (Ubuntu 4.8.2-16ubuntu6) 4.8.2, 64-bit
share|improve this question

1 Answer 1

up vote 2 down vote accepted

PostgreSQL doesn't support the RANGE clause yet. So even if you'd got the syntax right, it would've just failed with:

regress=> SELECT row_number() OVER (RANGE BETWEEN CURRENT ROW AND 42 FOLLOWING);
ERROR:  RANGE FOLLOWING is only supported with UNBOUNDED
LINE 1: SELECT row_number() OVER (RANGE BETWEEN CURRENT ROW AND 42 F...

To work around this, you can do a left outer join on generate_series(first_day, last_day, INTERVAL '1' DAY) then use a ROWS based window. That way a row exists for every day. It's a whole lot less efficient but unless you feel like getting your hands dirty in PostgreSQL's source code, it's probably the only option.

share|improve this answer
    
Interesting. So what is the difference between ROWS and RANGE? Why even have RANGE if you can't use expressions but instead need to specify a number of rows? –  ajw0100 May 29 at 5:49
    
Because RANGE is actually really useful - but PostgreSQL doesn't support it for non-trivial cases yet. I only used the above as a simplistic example to show that any attempt to use RANGE with correct syntax will throw an error indicating that PostgreSQL's support doesn't work yet. I admit that the error could be clearer, indicating that it's a PostgreSQL limitation not a fundamental limitation in the spec, though. See discussion: postgresql.org/message-id/… –  Craig Ringer May 29 at 7:02
    
and postgresql.org/message-id/… . It might help to understand that window functions are part of the SQL specification, which PostgreSQL is one implementation of. Like most implementations there are places where spec support is incomplete. This is one of them - PostgreSQL recognises the syntax for window functions with range windows, but doesn't know how to execute them yet. –  Craig Ringer May 29 at 7:03
    
Yea RANGE is extremely useful. I use it all the time in Oracle. Was hoping I could use it in Postgres as well. Thanks. –  ajw0100 May 29 at 7:32
    
@ajw0100 Well, your help with getting support into Pg would be valuable. Your time - updating and testing existing patches, seeking people interested, learning enough to develop it directly, etc - or more directly funding development. –  Craig Ringer May 29 at 7:42

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.