1

Basically, I have a table that looks like this:

Fruit | Juiciness | Brand | Price
---------------------------------
Apple |     2     |   A   | 0.50
Pear  |     1     |   A   | 0.70
Plum  |     6     |   A   | 0.40
Kiwi  |     5     |   B   | 0.80
Grape |     4     |   B   | 0.01

I'm looking to output two rows, one for brand A and one for brand B, with the name of the juiciest fruit (max juiciness value), and the sum price of all fruits from that brand. So:

Fruit | Brand | Price
---------------------------------
Plum  |   A   | 1.60
Kiwi  |   B   | 0.81

I was thinking of breaking it up into a few different CTE/subqueries, one with a simple SUM(Price) and one with a DISTINCT ON and ORDER BY to get the juiciest fruit and then joining them back together. But somehow even that wasn't working for me. (Something about me not wanting to display the juiciness seems to have been tripping Postgres up, but I'm not sure.)

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
Stephen Smith
  • 367
  • 1
  • 4
  • 12

2 Answers2

1

You want two aggregates: a sum and a maximum, and both times you want to group by brand. The challenging part is that you want the fruit name as well (otherwise it would be easy).

So first add the sum with a window function, then for each group fetch only the juiciest fruit:

SELECT DISTINCT ON (brand)
       fruit,
       brand,
       sum AS price
FROM (SELECT fruit,
             juiciness,
             brand,
             sum(price) OVER (PARTITION BY brand) AS sum
      FROM mytable) AS subq
ORDER BY brand, juiciness DESC;

With window functions, you often end up with subqueries.

Erwin Brandstetter
  • 605,456
  • 145
  • 1,078
  • 1,228
Laurenz Albe
  • 209,280
  • 17
  • 206
  • 263
1

Since DISTINCT or DISTINCT ON are applied after window functions, you can do this without subquery:

SELECT DISTINCT ON (brand)
       fruit, brand, sum(price) OVER (PARTITION BY brand) AS sum_price
FROM   tbl
ORDER  BY brand, juiciness DESC;

db<>fiddle here

Related:

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