MS Access 中的复杂比较

问题描述 投票:0回答:1

我几年前开始涉足 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;

如果有人能够以最有效的方式为我指明正确的方向,将每个分数与其他分数进行比较以返回最高值,我将永远感激不已。

vba ms-access ms-access-2016
1个回答
0
投票

考虑使用联合查询将所有分数堆叠在一起。 (理想情况下,这不是一个查询,而是如何实际存储数据,以便长时间保存数据以实现可扩展性和效率)。

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
© www.soinside.com 2019 - 2024. All rights reserved.