我几年前开始涉足 SQL,并休息了一段时间,所以我试图跟上新的做事方式,但我必须承认我不知道从哪里开始解决这个问题。 (可能是我自己做的!)。
我被要求编写一个数据库来帮助青年比赛日。其中一项比赛是急救,由 4 人组成的团队完成一个场景并获得分数。每个组织只能参加一个团队,所以1条记录 = 1个团队参赛。
计分方式如下: 每个团队成员都会根据个人表现进行评分,而团队则会根据他们的合作效率进行评分。将所有 5 个分数相加得出总分。 为了节省排名过程中的时间,我决定将组织名称的所有 6 个值存储在名为“tblFirstAidYouth”的表中(我还有一个 tblFirstAidAdult) 值名称为:FAY01Name; FAY01评分; FAY01名称; FAY02分数; FAY03名称; FAY03分数; FAY04名称; FAY04分数; FAYTeamScore; FAY总分.
qryFAY 然后对总体分数进行排序,给出排名的完成顺序。
为了增加混乱(无论如何我的混乱),竞争对手的名字是从另一个表中获取的,而不是手动输入的。这是因为检查第二个数据库以仅列出组织内在比赛当天未满 16 岁的人员。其输出作为 tblFAYCompetitors 输入到我的数据库中。 (前几年我们遇到了一些作弊问题,不合格的竞争对手参与竞争并获胜,因此这是添加某种形式的验证过程的努力。)无论如何,该表不是存储实际名称,而是存储来自 tblFAYCompetitors 的唯一 ID。并不是真正的问题,但在我看来,在该过程中添加了另一个步骤或查询。
我现在被要求做的是找出哪个“个人”团队成员得分最高,然后生成一份详细说明姓名、分数和组织的报告。
我的问题是,如何将每条记录中的 4 个单独分数与其他记录进行比较,以找到单个最高值? (或者在平局的情况下是多个?)
我有一个查询返回所有 4 名团队成员的详细信息。
我想我需要确定并返回每个团队的最高得分,然后将其与其他每个团队的最高得分进行比较。
如果一个团队中的 2 名成员得分相同,或者同一团队中的两名成员得分最高(因此总体排名第一和第二),则此情况会下降。
这是我到目前为止所拥有的: qryFAY
SELECT
tblFirstAidYouth.ID, tblFirstAidYouth.CompetitionID,
tblFirstAidYouth.FAYOrgID, tblFirstAidYouth.FAYTeam,
tblFirstAidYouth.FAY01Name, tblFirstAidYouth.FAY01Score,
tblFirstAidYouth.FAY02Name, tblFirstAidYouth.FAY02Score,
tblFirstAidYouth.FAY03Name, tblFirstAidYouth.FAY03Score,
tblFirstAidYouth.FAY04Name, tblFirstAidYouth.FAY04Score,
tblFirstAidYouth.FAYOverallScore, tblSqns.OrgNo, tblOrgs.OrgName
FROM
tblOrgs
RIGHT JOIN
tblFirstAidYouth ON tblOrgs.OrgID = tblFirstAidYouth.FAYOrgID;
如果有人能够以最有效的方式为我指明正确的方向,将每个分数与其他分数进行比较以返回最高值,我将永远感激不已。
考虑使用联合查询将所有分数堆叠在一起。 (理想情况下,这不是一个查询,而是如何实际存储数据,以便长时间保存数据以实现可扩展性和效率)。
SELECT
f.ID, f.CompetitionID,
f.FAYOrgID, f.FAYTeam,
f.FAY01Name AS FAYName, f.FAY01Score AS FAYScore,
o.OrgNo, o.OrgName,
f.FAYOverallScore
FROM tblFirstAidYouth f
LEFT JOIN tblOrgs o
ON o.OrgID = f.FAYOrgID
UNION ALL
SELECT
f.ID, f.CompetitionID,
f.FAYOrgID, f.FAYTeam,
f.FAY02Name, f.FAY02Score,
o.OrgNo, o.OrgName,
f.FAYOverallScore
FROM tblFirstAidYouth f
LEFT JOIN tblOrgs o
ON o.OrgID = f.FAYOrgID
UNION ALL
SELECT
f.ID, f.CompetitionID,
f.FAYOrgID, f.FAYTeam,
f.FAY03Name, f.FAY03Score,
o.OrgNo, o.OrgName,
f.FAYOverallScore
FROM tblFirstAidYouth f
LEFT JOIN tblOrgs o
ON o.OrgID = f.FAYOrgID
UNION ALL
SELECT
f.ID, f.CompetitionID,
f.FAYOrgID, f.FAYTeam,
f.FAY04Name, f.FAY04Score,
o.OrgNo, o.OrgName,
f.FAYOverallScore
FROM tblFirstAidYouth f
LEFT JOIN tblOrgs o
ON o.OrgID = f.FAYOrgID
从那里导出一个行号,对所有参与者的分数进行排序。希望很快,MS Access SQL 将像其他 DBMS 一样支持窗口函数。在此之前,相关的
DCount
或计数聚合就可以发挥作用。但将联合查询保存在新表中可能会更有效(如上所述,该表应该是您的原始数据源结构)。
SELECT * INTO myScoresTable FROM myUnionQuery
下面列出了队内得分和总分排名,特殊情况是两个最高分可能在同一队。您可以对团队总得分做同样的事情。
SELECT
s.ID, s.CompetitionID,
s.FAYOrgID, s.FAYTeam,
s.FAYName, s.FAYScore,
s.OrgNo, s.OrgName,
s.FAYOverallScore,
(SELECT COUNT(*)
FROM myScoresTable sub_s
WHERE
sub_s.OrgNo = s.OrgNo AND
sub_s.FAYScore >= s.FAYScore
) AS FAYScoreWithinTeamRank,
(SELECT COUNT(*)
FROM myScoresTable sub_s
WHERE sub_s.FAYScore >= s.FAYScore
) AS FAYScoreRank
FROM myScoresTable s
最终查询选择得分最高的个人或更多人作为平局。如果得分最高的球员来自同一支球队,请手动调整下一个得分最高的球员的排名过滤器,例如
FAYScoreRank <= 2
。在 SQL 中实现自动化会变得很复杂。您可以将上面嵌套在下面作为派生表。
SELECT *
FROM myRankScoreQuery
WHERE FAYScoreRank = 1