1

I have a table with columns: FILING_ID, DATE, and BLAH

I'm trying to write a query that for each FILING_ID, returns the rows with the last three dates. If table is:

   FILING_ID   DATE    
     aksjdfj   2/1/2006
           b   2/1/2006
           b   3/1/2006
           b   4/1/2006
           b   5/1/2006

I would like:

   FILING_ID   DATE    
     aksjdfj   2/1/2006
           b   3/1/2006
           b   4/1/2006
           b   5/1/2006

I was thinking of maybe running some query to figure out the 3rd highest date for each FILING_ID then doing a join and comparing the cutoff date with the DATE?

I use PostgreSQL. Is there some way to use limit?

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
Matthew Gunn
  • 4,451
  • 1
  • 12
  • 30

1 Answers1

1
SELECT filing_id, date  -- more columns?
FROM  (
   SELECT *, row_number() OVER (PARTITION BY filing_id ORDER BY date DESC NULLS LAST) AS rn
   FROM   tbl
   ) sub
WHERE  rn < 4
ORDER  BY filing_id, date;  -- optionally order rows

NULLS LAST is only relevant if date can actually be NULL.
If date is not unique, you may need to break ties to get stable results.

Is there some way to use limit?

Maybe. If you have an additional table holding all distinct filing_id (and possibly a few more, which are removed by the join), you can use CROSS JOIN LATERAL (, LATERAL is short syntax):

SELECT f.filing_id, t.*
FROM   filing f  -- table with distinct filing_id
     , LATERAL (
   SELECT date -- more columns?
   FROM   tbl
   WHERE  filing_id = f.filing_id
   ORDER  BY date DESC NULLS LAST
   LIMIT  3  -- now you can use LIMIT
   ) t
ORDER  BY f.filing_id, t.date;

If you don't have a filing table, you can create one. Or derive it on the fly:

Community
  • 1
  • 1
Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228