Search code examples
sqlsubqueryaggregate-functionstop-n

aggregation subquery with top N


Let's say I have a table called COFFEE showing Bus Stations and all of the coffee shops within 10 blocks of the bus station:

    BusStationID| CoffeeShopID |  Distance (in city blocks)
    1|2103|2
    1|2222|2
    1|8864|7
    1|9920|5
    1|3544|2
    1|4830|2
    1|4823|6
    1|9561|2
    7|6262|2
    7|8561|10
    7|9510|5
    7|2744|1       
    7|4223|9
    7|5960|3

[EDITED: to make clear that the question is how to do this with a query not procedurally]

And I have to write a query (not a proc) to show for each bus-station, the average distance to the five closest coffee shops.

I can get the top 5 closest coffee shops for a particular bus-station:

           select avg(top5.distance) as AvgDistToFiveClosest
           from
           (
           select top 5 distance from COFFEE where busstationid = 1
           order by distance
           ) as top5

But how do I connect that as a subquery and make AvgDistToFiveClosest a column returned in my main query:

        select BusStationId,  AvgDistToFiveClosest
        from COFFEE...
         ??????

Given the sample data above, the query should return:

     BusStationID | AvgDistToFiveClosest
           1 | 2
           7 | 4

Solution

  • Try this:

    SELECT c.BusStationID, AVG(c.distance)
    FROM COFFEE c
    WHERE c.CoffeeShopID IN 
    (SELECT TOP 5 c2.CoffeeShopID FROM COFFEE c2 WHERE c2.BusStationID = c.BusStationID
    ORDER BY c2.distance)
    GROUP BY c.BusStationID