2

我想结合

Select top 2 scouting.* From scouting Where scouting.astroLoc Like 'D01%' AND scouting.ownerGuild = 'SWARM' Order By scouting.jumpGate Desc

Select top 2 scouting.* From scouting Where scouting.astroLoc Like 'D02%' scouting.ownerGuild = 'SWARM' Order By scouting.jumpGate Desc

Select top 2 scouting.* From scouting Where scouting.astroLoc Like 'D03%' scouting.ownerGuild = 'SWARM' Order By scouting.jumpGate Desc

一直持续到

Select top 2 scouting.* From scouting Where scouting.astroLoc Like 'D79%' scouting.ownerGuild = 'SWARM' Order By scouting.jumpGate Desc

... 到 1 个 SQL 查询中,其中 TOP 3 记录按 scouting.astroLoc 升序分组。

4

2 回答 2

2

这是 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 个。s2astroLocjumpGateHAVINGs1

这假设行在 [ 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 习惯于在顶部编辑您的原始问题帖子。

于 2009-11-22T01:13:13.517 回答
0

问题只发生了非常轻微的变化,需要更多的 astroloc D[0-7][0-9] 值,受 owner.Guild = 'SWARM' 的限制......我做了一些非常类似于将 astroloc 拆分为 2 个字段的事情。相反,我创建了一个新表(星系),其中包含我需要的部分 astroloc 数据(前 3 个字符,减去“D”),并使用唯一 ID 引用它:

Select scouting.astroLoc, galaxy.[galaxy_aename], scouting.jumpGate, scouting.ownerGuild From galaxy Inner Join scouting On galaxy.[galaxy_ID] = scouting.galaxy Where (scouting.jumpGate) In (Select Top 3 scouting.jumpGate From scouting Where scouting.galaxy = galaxy.[galaxy_ID] Order By scouting.jumpGate Desc) Order By scouting.astroLoc Desc, scouting.jumpGate Desc

问题是它遗漏了一些类别(galaxy.[galaxy_ID])值。星系表有 0 到 79 个条目,在侦察表中,每个星系都至少被引用和交叉链接一次,所以你不会期望它错过一个类别 (galaxy.[galaxy_ID])。有什么想法吗?

于 2009-11-25T11:46:06.417 回答