简体   繁体   中英

Not sure how to write a query to return column associated with max value in group by

This query in postgres 9.2:

select max(amount) as max_analyte,concat(sarea,' ',sloc) as location,analyte
from sample natural join station
group by analyte,location
order by max_analyte desc;

returns the following results:

max_analyte;location;analyte
24196;"CANDLESTICK POINT WINDSURFER CIRCLE";"COLI_TOTAL  "
19863;"CHINA BEACH/BAKER BEACH LOBOS CREEK";"COLI_TOTAL  "
14136;"CRISSY FIELD EAST";"COLI_TOTAL  "
12033;"CHINA BEACH/BAKER BEACH BAKER BEACH WEST";"COLI_TOTAL  "
4352;"CHINA BEACH/BAKER BEACH LOBOS CREEK";"COLI_E      "
3076;"CHINA BEACH/BAKER BEACH BACKER BEACH EAST";"COLI_TOTAL  "
2851;"CHINA BEACH/BAKER BEACH LOBOS CREEK";"ENTERO      "
2064;"AQUATIC PARK SHORELINE";"COLI_TOTAL  "
1918;"CRISSY FIELD EAST";"ENTERO      "
...
...

74;"CHINA BEACH/BAKER BEACH CHINA BEACH";"ENTERO      "
41;"CRISSY FIELD WEST";"ENTERO      "
41;"OCEAN BEACH NORTH LINCOLN WAY";"ENTERO      "
31;"OCEAN BEACH NORTH LINCOLN WAY";"COLI_E      "

The data set contains the levels of 3 types of bacteria (COLI_TOTAL, COLI_E, ENTERO) sampled at various locations around the Bay Area on many different dates. The query above finds the max value at each location for each type of bacteria, but now I'd like to find which type of bacteria is associated with the maximum value for each location. I'm just not sure how to write that query. I should mention I'm doing this to improve my SQL skills. Thanks for any help/suggestions.

The tables schemas are as follows:

CREATE TABLE sample
(
  analyte character(12),
  amount integer,
  sdate date,
  sid character varying(20)
)

CREATE TABLE station
(
  sid character(20),
  sarea character varying(24),
  sloc character varying(24),
  sfreq character varying(24)
)

It's a bit complicated, but here's a working solution:

with cte as (
select max(amount) as max_analyte,
       concat(sarea,' ',sloc) as location,
       analyte
from sample natural join station
group by analyte,location
)
select location, analyte, max_analyte
from (
  select location, analyte, max_analyte,
         row_number() over (partition by location order by max_analyte desc) rn
  from cte
) A
where rn = 1;

The with cte part basically wraps your previous query up so it can be used again later on, referring to it as cte as if it were just another table (this is called a common table expression). Then that CTE is used in a subquery that numbers the rows starting at 1 for each location. The portion of the query in parentheses after the over tells row_number() how to order the rows it's numbering and when to start over at 1. Then at the end it's all wrapped up when we grab row number 1 (the max for each location).

I think I got a working solution:

select distinct concat(sarea,' ',sloc), analyte, amount from 
    (sample natural join station) as t1 
    join
    (
        select sid,max(amount) as max_amount from 
        sample group by sid
    ) as t2 
    on t1.sid=t2.sid and t1.amount=t2.max_amount
    order by amount desc;

"CANDLESTICK POINT WINDSURFER CIRCLE";"COLI_TOTAL  ";24196
"CHINA BEACH/BAKER BEACH LOBOS CREEK";"COLI_TOTAL  ";19863
"CRISSY FIELD EAST";"COLI_TOTAL  ";14136
"CHINA BEACH/BAKER BEACH BAKER BEACH WEST";"COLI_TOTAL  ";12033
"CHINA BEACH/BAKER BEACH BACKER BEACH EAST";"COLI_TOTAL  ";3076
"AQUATIC PARK SHORELINE";"COLI_TOTAL  ";2064
"CANDLESTICK POINT SUNNYDALE COVE";"COLI_TOTAL  ";1723
"CANDLESTICK POINT JACKRABBIT BEACH";"COLI_TOTAL  ";1529
"AQUATIC PARK HYDE STREET PIER";"COLI_TOTAL  ";933
"CRISSY FIELD WEST";"COLI_TOTAL  ";884
"OCEAN BEACH NORTH BALBOA STREET";"COLI_TOTAL  ";789
"OCEAN BEACH SOUTH SLOAT";"COLI_TOTAL  ";771
"OCEAN BEACH NORTH LINCOLN WAY";"COLI_TOTAL  ";563
"CHINA BEACH/BAKER BEACH CHINA BEACH";"COLI_TOTAL  ";328

Looks like "COLI_TOTAL" is always the max for each location, which makes sense considering the name.

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