这是 StackOverflow 上经常发布的“greatest-n-per-group”问题。这是一个解决方案:
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;
这是有效的,因为查询尝试将给定的行与具有相同和更大值s1
的行集相匹配。该子句将结果限制为匹配少于两个的行,这意味着该行将位于前 2 个。s2
astroLoc
jumpGate
HAVING
s1
这假设行在 [ astroLoc
, jumpGate
] 上是唯一的。如果没有,您可能需要在连接条件中添加另一个术语来解决关系。
重新发表评论,尝试以下更改:
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;
这仅比较前三个字符的astroLoc
目的是为了测试一行是否与另一行在同一个“组”中,并且它还jumpGate
通过使用主键来解决关系。
用新要求重新回答您的其他答案:
scouting.ownerGuild
= 'SWARM' 去哪儿了?
很难按照您的要求进行操作,因为我不知道您的表定义或列的含义是什么。您是否希望外部查询与 SWARM 公会拥有的前三个跳跃门相匹配?
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
这将是与此查询不同的查询,它使外部查询返回 SWARM 拥有的 jumpgate 与任何人拥有的前三个 jumpgate 匹配。
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
如果没有一个 SWARM jumpgate 在前三个中,那么第二个查询可能会返回一个空结果。
PS:当您需要添加更多细节或后续问题时,StackOverflow 习惯于在顶部编辑您的原始问题帖子。