Search code examples
sqlpostgresqlpostgresql-13

PostgreSQL — Select column1 where MIN(column2)


NOTE: I WANT TO AVOID DISTINCT ON FOR PERFORMANCE REASONS.

NOTE 2: I WAS WRONG. USING PROPER INDEXES THE QUERY WORKED AWESOME THANKS TO @Gordon Linoff!

Having the following structure:

| id | image_url     | sort | t1_id |
|----|---------------|------|-------|
| 1  | https://.../1 | 10   | 1     |
| 2  | https://.../2 | 20   | 1     |
| 3  | https://.../3 | 30   | 1     |
| 4  | https://.../4 | 30   | 2     |
| 5  | https://.../5 | 20   | 2     |
| 6  | https://.../6 | 10   | 2     |

I want to fetch the lowest sort row's image_url column by t1_id, similar to the following:

SELECT * FROM t2 WHERE MIN(sort) GROUP BY (t1_id);

Getting the following result:

| id | image_url     | sort | t1_id |
|----|---------------|------|-------|
| 1  | https://.../1 | 10   | 1     |
| 6  | https://.../6 | 10   | 2     |

Thanks in advance!


Solution

  • Postgres has a handy extension called distinct on:

    select distinct on (t1_id) t2.*
    from t2
    order by t1_id, sort asc;
    

    This is usually the fastest way to approach such a problem. In particular, this can take advantage of an index on (t1_id, sort [desc]).

    However, you can try another approach such as:

    select t2.*
    from t2
    where t2.sort = (select min(tt2.sort)
                     from t2 tt2
                     where tt2.t1_id = t2.t1_id
                    );
    

    This would use the same index. If this is faster, please post a comment with the relevant performance.