简体   繁体   中英

Selecting Max from subquery Oracle

I'm using Oracle and trying to find the maximum transaction count (and associated date) for each station.

This is the code I have but it returns each transaction count and date for each station rather than just the maximum. If I take the date part out of the outer query it returns just the maximum transaction count for each station, but I need to know the date of when it happened. Does anyone know how to get it to work?

Thanks!

SELECT STATION_ID, STATION_NAME, MAX(COUNTTRAN), TESTDATE
FROM 
(
    SELECT COUNT(TRANSACTION_ID) AS COUNTTRAN, STATION_ID, 
           STATION_NAME, TO_CHAR(TRANSACTION_DATE, 'HH24') AS TESTDATE
    FROM STATION_TRANSACTIONS 
    WHERE COUNTRY = 'GB' 
    GROUP BY STATION_ID, STATION_NAME, TO_CHAR(TRANSACTION_DATE, 'HH24')
)
GROUP BY STATION_ID, STATION_NAME, TESTDATE
ORDER BY MAX(COUNTTRAN) DESC

This image shows the results I currently get vs the ones I want:

在此处输入图片说明

What your query does is this:

  1. Subquery: Get one record per station_id, station_name and date. Count the transactions for each such combination.
  2. Main query: Get one record per station_id, station_name and date. (We already did that, so it doesn't change anything.)
  3. Order the records by transaction count.

This is not what you want. What you want is one result row per station_id, station_name, so in your main query you should have grouped by these only, excluding the date:

select  
  station_id, 
  station_name, 
  max(counttran) as maxcount,
  max(testdate) keep (dense_rank last over order by counttran) as maxcountdate
from 
(
  select 
    count(transaction_id) as counttran, 
    station_id, 
    station_name, 
    to_char(transaction_date, 'hh24') as testdate
  from station_transactions 
  where country = 'GB' 
  group by station_id, station_name, to_char(transaction_date, 'hh24')
)
group by station_id, station_name;

An alternative would be not to group by in the main query again, for actually you already have the desired records already and only want to remove the others. You can do this by ranking the records in the subquery, ie give them row numbers, with #1 for the best record per station (this is the one with the highest count). Then dismiss all others and you are done:

select station_id, station_name, counttran, testdate
from 
(
  select 
    count(transaction_id) as counttran,
    row_number() over(partition by station_id order by count(transaction_id) desc) as rn
    station_id, 
    station_name, 
    to_char(transaction_date, 'hh24') as testdate
  from station_transactions 
  where country = 'GB' 
  group by station_id, station_name, to_char(transaction_date, 'hh24')
)
where rn = 1;

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