0

Suppose I have a single table foo, with relevant columns flag, date and username.

I am struggling to come up with a PostgreSQL query that does the following:

Select all rows where...

  • date is later than a specific date
  • and flag = 0
  • and there is NO other row of a later date and with flag = 1 for the same user

...grouped by username.

The problem is very much the third requirement in the list above. I have tried building the query using subqueries with EXCEPT, WHERE NOT EXISTS, WITH and LATERAL, but I always run into a dead end when the dates of the subqueries must be compared to each other and I cannot reference them.

Is this possible within a single SQL statement?

1
  • 1
    Please provide sample data and desired results. Your current query would also help. Commented May 17, 2018 at 14:52

1 Answer 1

1

This looks a lot like not exists:

select t.* from t where date > ? and flag = 0 and not exists (select 1 from t t2 where t2.username = t.username and t2.flag = 1 and t2.date > t.date ); 

If you just want user names meeting the condition, conditional aggregation should suffice:

select username from t where date > ? group by username having min(case when flag = 0 then date end) < max(case when flag = 1 then date end); 

This is saying that the last flag = 1 date is later than the earliest flag = 0.

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

2 Comments

Thank you, this looks very promising! Could you explain what the having line in your second example does? I don't understand how the min/max functions work in combination with case.
@Hatch . . . I would suggest that you try min(case . . .) and max(case . . .) in some queries on your data (in the select), so you will see what happens.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.