Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get primary key of aggregated, group by SQL query using PostgreSQL

Tags:

sql

postgresql

I'm struggling with creating a SQL query involving aggregates using PostgreSQL. Consider the following tables:

CREATE TABLE thing (
  id INT NOT NULL PRIMARY KEY,
  price NUMERIC(10,2) NOT NULL,
  description VARCHAR(255) NOT NULL,
  url VARCHAR(255) NOT NULL,
  location_id INT NOT NULL REFERENCES location(id)
)

CREATE TABLE location (
  id INT NOT NULL PRIMARY KEY,
  type INT NOT NULL,
  name VARCHAR(255) NOT NULL
)

Now, I would like to get all the thing records for each location with location.type = xxx that have the lowest price.

Something like:

SELECT min(price) FROM thing
INNER JOIN location ON (thing.location_id = location.id)
WHERE type = xxx
GROUP BY location_id

This will list me the lowest price for each location with type xxx, but how can I get the rows (or their primary keys) of these columns from table thing?

like image 263
Haes Avatar asked Jan 31 '26 10:01

Haes


1 Answers

Use this PostgreSQL extension:

SELECT  DISTINCT ON (location.id) thing.*
FROM    location
JOIN    thing
ON      thing.location_id = location_id
WHERE   type = 1
ORDER BY
        location.id ASC, price ASC

This will select only the first row for each location.id.

Since your rows are sorted by location.id then by price, this will be the row with the minimal price.

In new PostgreSQL 8.4, you can also use window functions:

SELECT  *
FROM    (
        SELECT  thing.*, ROW_NUMBER() OVER (PARTITION BY location_id ORDER BY price) AS rn
        FROM    location
        JOIN    thing
        ON      thing.location_id = location_id
        WHERE   type = 1
        ) q
WHERE   rn = 1
like image 124
Quassnoi Avatar answered Feb 03 '26 03:02

Quassnoi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!