简体   繁体   中英

How to get max of column based on grouping by date column in postgreSQL

First time poster here, not sure if my title really outlines what I am looking for here...

I am trying to get the following:

"Which month of the year does each property type earn the most money on average?"

I have two tables with the following fields I am working with:

calendar_metric
    period (this is a date, formatted 'yyyy-mm-dd'
    revenue
    airbnb_property_id
property
    property_type
    airbnb_property_id

I have figured out how to get the month, property type, and average revenue to display, but am having trouble with grouping it correctly I think.

select
    extract(month from calendar_metric.period) as month,
    property.property_type,
    avg(calendar_metric.revenue) as average_revenue
from
    calendar_metric
inner join property on
    calendar_metric.airbnb_property_id = property.airbnb_property_id
group by
    month,
    property_type

What I want it to output would look like this:

month | property_type | max_average_revenue
---------------------------------------------
   1  |   place       | 123
   2  |   floor apt   | 535
   3  |   hostel      | 666
   4  |   b&b         | 363
   5  |   boat        | 777
   etc|   etc         | etc

but currently I am getting this:

month-property_type | max_average_revenue
---------------------------------------------
   1  |   place       | 123
   2  |   floor apt   | 535
   1  |   place       | 444
   4  |   b&b         | 363
   4  |   b&b         | 777
   etc|   etc         | etc

So essentially, months are coming back duplicated as I extracted the month from a date stamp, the data set goes across 5 years or so, and am probably not grouping right? I know I am missing something simple probably, I just cannot seem to figure out how to do this correctly.

Help!

you should be grouping by year-month , since you are trying to view 5 year period.

select
    extract(month from calendar_metric.period) as month,
    property.property_type,
    avg(calendar_metric.revenue) as average_revenue
from
    calendar_metric
inner join property on
    calendar_metric.airbnb_property_id = property.airbnb_property_id
group by
    extract(year from period),
    month,
    property_type

I think your query is basically there, it's just returning all months rather than just filtering out the rows you don't want. I'd tend to use the DISTINCT ON clause for this sort of thing, something like:

SELECT DISTINCT ON (property_type)
  p.property_type, extract(month from cm.period) AS month,
  avg(cm.revenue) AS revenue
FROM calendar_metric AS cm
  JOIN property AS p USING (airbnb_property_id)
GROUP BY property_type, month
ORDER BY property_type, revenue DESC;

I've shortened your query down a bit, hope it still makes sense to you.

using CTEs you can express this in two steps which might be easier to follow what's going on:

WITH results AS (
  SELECT p.property_type, extract(month from cm.period) AS month,
    avg(cm.revenue) AS revenue
  FROM calendar_metric AS cm
    JOIN property AS p USING (airbnb_property_id)
  GROUP BY property_type, month
)
SELECT DISTINCT ON (property_type)
  property_type, month, revenue
FROM results
ORDER BY property_type, revenue DESC;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM