This is the "greatest-n-per-group" problem that is posted frequently on StackOverflow. Here's a solution:
SELECT s1.*
FROM scouting s1
LEFT OUTER JOIN scouting s2
ON (s1.astroLoc = s2.astroLoc AND s1.jumpGate < s2.jumpGate)
WHERE s1.astroLoc LIKE 'D[3-7][0-9]%' AND s1.astroLoc NOT LIKE 'D3[0-2]%'
GROUP BY s1.* -- here you need to name all fields in the select-list
HAVING COUNT(*) < 2;
This works because the query tries to match a given row s1
to the set of rows s2
that have the same astroLoc
and a greater jumpGate
value. The HAVING
clause restricts the result to s1
rows that match fewer than two, which means that the row would be in the top 2.
This assumes rows are unique over [astroLoc
, jumpGate
]. If not, you may need to add another term to the join condition to resolve ties.
Re your comment, try the following alteration:
SELECT s1.*
FROM scouting s1
LEFT OUTER JOIN scouting s2
ON (SUBSTRING(s1.astroLoc, 1, 3) = SUBSTRING(s2.astroLoc, 1, 3)
AND (s1.jumpGate < s2.jumpGate OR (s1.jumpGate = s2.jumpGate AND s1.ID < s2.ID))
WHERE s1.astroLoc LIKE 'D[3-7][0-9]%' AND s1.astroLoc NOT LIKE 'D3[0-2]%'
GROUP BY s1.* -- here you need to name all fields in the select-list
HAVING COUNT(*) < 2;
This compares only the first three characters of astroLoc
for purposes of testing a row is in the same "group" as the other, and it also resolves ties in jumpGate
by using the primary key.
Re your other answer with new requirements:
where does the scouting.ownerGuild
= 'SWARM' go?
It's hard to follow what you're asking for, since I don't know what are your table definitions or the meanings of columns. Do you want the outer query to be matched to the top three jumpgates that are owned by the SWARM guild?
SELECT s1.astroLoc, g.[galaxy_aename], s1.jumpGate, s1.ownerGuild
FROM galaxy g INNER JOIN scouting s1 ON g.[galaxy_ID] = s1.galaxy
WHERE s1.jumpGate IN (SELECT TOP 3 s2.jumpGate FROM scouting AS s2
WHERE s2.galaxy = g.[galaxy_ID] AND s2.ownerGuild = 'SWARM'
ORDER BY s2.jumpGate DESC)
ORDER BY scouting.astroLoc DESC, scouting.jumpGate DESC
That would be a different query from this one, which makes the outer query return the jumpgates owned by SWARM that match the top three jumpgates owned by anyone.
SELECT s1.astroLoc, g.[galaxy_aename], s1.jumpGate, s1.ownerGuild
FROM galaxy g INNER JOIN scouting s1 ON g.[galaxy_ID] = s1.galaxy
WHERE s1.jumpGate IN (SELECT TOP 3 s2.jumpGate FROM scouting AS s2
WHERE s2.galaxy = g.[galaxy_ID]
ORDER BY s2.jumpGate DESC)
AND s1.ownerGuild = 'SWARM'
ORDER BY scouting.astroLoc DESC, scouting.jumpGate DESC
It's possible the second query will return an empty result, if none of the SWARM jumpgates are in the top three.
PS: It's customary on StackOverflow to edit your original question post at the top, when you need to add more detail or followup questions.