Reputation: 484
What is a way to write a SQL query for Access that will group by a certain criterion, then order inside the group by different criteria, that were not used to group by? For example, suppose I have a table called tblObjects, with columns:
autoID name color shape weight height
I want to end up with a list of objects that does not repeat color, and that selects the tallest object in each color group. If there are objects of same color, same height, then select the heaviest.
I figured I can group by color, order inside the group by height and then weight and then truncate at 1. That should eliminate all color repetition and pick the one "representative" of each color according to my criteria.
After researching here I was able to group by with the code:
SELECT autoID, name, color, shape, weight, height
FROM tblObjects INNER JOIN( SELECT
color, COUNT(*) AS NumberSameColor
FROM tblObjects
GROUP BY color) AS tblGroups ON tblObjects.color = tblGroups.color;
but when I try to ORDER BY height, weight
I get an error saying that the columns I am trying to use to order by is not part of the aggregation. If I put "order by" statement at the end of the query, it undoes the groups in favor of the ordering.
How can I get around this limitation to get the results that I need?
I see that I don't actually need the count, so do I even need to aggregate? Am I missing a significantly simpler way to approach this?
Upvotes: 0
Views: 237
Reputation: 1270421
This should work:
SELECT o.autoID, o.name, o.color, o.shape, o.weight, o.height,
c.NumberSameColor -- added so the `JOIN` makes sense
FROM tblObjects as o INNER JOIN
(SELECT color, COUNT(*) AS NumberSameColor
FROM tblObjects
GROUP BY color
) AS c
ON o.color = c.color
ORDER BY o.weight, o.height;
I just added the table aliases to remove ambiguity about where the columns come from.
EDIT:
Hmmm, I think you want this:
select o.*
from tblObjects as o
where o.height = (select max(o2.height)
from tblObjects as o2
where o2.color = o.color
);
There is no group by
at all. This says to choose all objects whose height is the largest value for their color. Of course, there could be more than one for a given color. For that:
select o.*
from tblObjects as o
where o.autoid = (select top 1 o2.autoid
from tblObjects as o2
where o2.color = o.color
order by o2.height desc, o2.weight desc, o2.autoid
);
Upvotes: 2