MS Access 中的 SQL JOIN 问题
Posted
技术标签:
【中文标题】MS Access 中的 SQL JOIN 问题【英文标题】:SQL JOIN Issue in MS Access 【发布时间】:2012-04-23 14:10:46 【问题描述】:我正在处理的一些 SQL 中的连接语句有点麻烦。想知道是否有任何聪明的人可以帮助我解决我的问题!
我正在尝试加入 3 个表:tblMember、tblResult 和 tblPoint
tblMember - 包含用户信息,例如姓名和电子邮件。 tblResult - 包含会员和他们报名参加的比赛的详细信息,只要他们完成比赛的位置和时间的详细信息。 tblPoint - 包含一组与一个人在比赛中完成的位置相关的积分,例如,第 1 名获得 10 分,第 2 名获得 8 分……如果一个人获得第 6 名或以下,则不分配积分。
我希望查询返回 tblResult.ResultID、tblMember.MemberName、tblResult.PersonalTime、tblResult.FinishPosition、tblPoint.Points。但我希望它返回所有这些字段,即使 FinishPosition 为空且没有分配积分。
通过使用下面的这条 SQL,我几乎解决了这个问题:
SELECT DISTINCT tblResult.ResultID, tblMember.MemberName, tblResult.PersonalTime,
tblResult.FinishPosition, tblPoint.Points
FROM (tblMember INNER JOIN tblResult ON tblMember.MemberID = tblResult.MemberID) LEFT
JOIN tblPoint ON tblResult.FinishPosition = tblPoint.Position;
然而这并不完全奏效。当我的查询返回结果时,已经分配了一个位置(例如第二名)的人被多次返回,第一次分配了第一名的分数,然后第二次分配了第二名的分数!
这一定是一个 JOIN 问题...但我不知道如何纠正它! 我已经尝试过使用 IIF 和 ISNULL,但我认为这不是正确的使用方法。
我使用的 MS Access 似乎不支持 LEFT OUTER JOIN、RIGHT OUTER JOIN 或 FULL JOIN。
有人可以帮忙吗?感谢您阅读本文。 :)
编辑: [tblPoint] 包含字段(PointID、RaceTypeID、Points、Position)。每种比赛类型有 5 行。 PointID 是主键,表可能如下所示:
点 ID - 1,RaceTypeID - 1,点 - 10,位置 - 1
点 ID - 2,RaceTypeID - 1,点 - 6,位置 - 2
点 ID - 3,RaceTypeID - 1,点 - 3,位置 - 3
点 ID - 4,RaceTypeID - 1,点 - 2,位置 - 4
点 ID - 5,RaceTypeID - 1,点 - 1,位置 - 5。
这意味着对于比赛类型 1,第 1 名获得 10 分,第 2 名获得 6 分,依此类推。该表可以支持不同的比赛类型,每种比赛类型都有自己的积分系统。
成员可以在 tblResult 中出现任意次数,一旦成员“注册”参与,他们就会出现在 tblResult 中,没有分配完成位置或个人时间。
【问题讨论】:
我认为最好的办法是发布一些示例数据。例如,成员多久可以出现在结果表中?积分表中是否只有 5 行? Access 支持LEFT OUTER JOIN
和RIGHT OUTER JOIN
但不支持FULL OUTER JOIN
(但请注意LEFT OUTER JOIN
和RIGHT OUTER JOIN
的并集与FULL OUTER JOIN
相同)。
刚刚编辑了我的原始帖子以包含您建议的信息,有没有机会让它更清楚? @onedaywhen。你认为这是我需要的完全外部连接吗?我在网上看到过有关如何在线重新创建 FULL OUTER JOIN 的文章。
嗨 LNB 如果您在积分表中有所有这些额外的行,您将需要加入比赛类型和位置。您还没有在示例查询中这样做。
【参考方案1】:
对于其他有同样问题的人:
正如 REMOU 指出的那样,我错过了 tblRaceType 的另一个连接,谢谢! 这是我最后的 SQL 代码。
SELECT tblResult.ResultID, tblMember.MemberName, tblResult.PersonalTime,
tblResult.FinishPosition, tblPoint.Points
FROM tblRaceType RIGHT JOIN ((tblMember INNER JOIN tblResult ON tblMember.MemberID =
tblResult.MemberID) LEFT JOIN tblPoint ON tblResult.FinishPosition = tblPoint.Position) ON
tblRaceType.RaceTypeID = tblPoint.RaceTypeID;
【讨论】:
【参考方案2】:MS Access 在混合JOIN
s 和LEFT JOIN
s 时总是遇到问题。将查询拆分为两个子查询。这是 MS Access 的最佳策略,您无需调整性能。
而且,如果这没有帮助,请尝试在图形界面中创建查询,因为 MS Access 可能无法理解 SQL 源...记住,它是 MS :-) 只需单击即可。表现得像 MS 期望的那样 - 像一个简单的用户:-)
尝试这些方法 - 即“尽可能简单”地使用 Access,根据我的经验,您会发现问题所在。此外,通过子查询策略(使用简单步骤构建查询),您可以测试子结果。
【讨论】:
“MS Access 在混合 JOIN 和 LEFT JOIN 时总是遇到问题”——这不是我的经验。 @MitchWheat 完全同意,这可以在不创建两个子查询的情况下完成 当 Access 数据库引擎的性能足以应付手头的任务时,请使用它。我认为您抨击 Access 的态度对于回答 OP 的 MS Access 问题并没有真正的帮助。 " 或对于非常小的数据库" 小于 2 GB 可能涵盖大量数据库,例如社区游戏。 @HansUp:“在性能足以应付手头任务的情况下使用 Access 数据库引擎”——我不能同意您选择一个 DBMS 而非另一个 DBMS 的标准。 Access 有一些相当基本的缺陷和错误。我不在乎它会给我一个“错误”的结果多快。以上是关于MS Access 中的 SQL JOIN 问题的主要内容,如果未能解决你的问题,请参考以下文章
MS-Access 中的 SQL:使用 COUNT、JOIN 并返回 0
MS Access SQL 多个 JOIN 和 WHERE 子句
MS Access / SQL Server JOIN返回左表中的所有值,如果右侧缺少则返回零
MS Access 2007 语法:From Join Join Join Where