在 MS Access 中加入 3 个或更多表而不重复条目
Posted
技术标签:
【中文标题】在 MS Access 中加入 3 个或更多表而不重复条目【英文标题】:Joining 3 or more tables without duplicating entries in MS Access 【发布时间】:2018-03-12 12:19:55 【问题描述】:我目前正在练习我的访问技能,希望对以下问题提供任何帮助。
问题是我正在尝试将 3 个表合并为一个。我将其中一个用作主表(事实表),而其他 2 个表有关于该事实的额外信息,但是信息相同但来自不同的来源。您可以在下面看到一个示例(我仍在弄清楚***,所以我很抱歉造型不佳)
事实表
Name Age Gender
Nordon 21 male
额外信息
Name Skills Level
Nordon Programming Good
Nordon Singing Poor
Nordon Drawing Good
ExtraInfo_2
Name Skills Level
Nordon Programming Good
Nordon Singing Good
Nordon Drawing Poor
当我尝试在 Access 中使用 Inner Join 执行语句时,我得到如下信息:
结果
Name Age Gender Skills_1 Skills_2 Level_1 Level_2
Nordon 21 male programming programming Good Good
Nordon 21 male programming Singing Good Good
Nordon 21 male programming Drawing Good Poor
Nordon 21 male Singing programming Poor Good
Nordon 21 male Singing Singing Poor Good
Nordon 21 male Singing Drawing Poor Poor
基本上它是将表 1 中的技能映射到表 2 中的每个技能。我期待的是这样的:
结果
Name Age Gender Skills_1 Skills_2 Level_1 Level_2
Nordon 21 male programming programming Good Good
Nordon 21 male Singing Singing Poor Good
Nordon 21 male Drawing Drawing Good Poor
基本上,我想检查不一致之处,但我会自己做。有时,表 Skills_1 和 Skills_2 的每个事实的条目数量也不同。有没有办法解决这个问题?
感谢所有帮助!
【问题讨论】:
还不能添加评论。 This 可能会有所帮助。 我也在看,下面提到了,谢谢! 【参考方案1】:有很多不同的方法可以做到这一点,但使用INNER JOIN
s 我猜你只是没有在技能名称上包含两个额外信息表之间的链接?在这种情况下,这样的事情应该可以工作:
SELECT
f.Name,
f.Age,
f.Gender,
ei1.Skills AS Skills_1,
ei2.Skills AS Skills_2,
ei1.Level AS Level_1,
ei2.Level AS Level_2
FROM
Fact f
INNER JOIN ExtraInfo ei1 ON ei1.Name = f.Name
INNER JOIN ExtraInfo_2 ei2 ON ei2.Name = f.Name AND ei2.Skills = ei1.Skills
如果您在 Extra Info 表中存在潜在的空白,那么您将需要改用 LEFT JOIN
s,这变得更加棘手,因为在 ExtraInfo_2 与 ExtraInfo 相关的地方,连接条件将停止工作。在这种情况下,您需要使用子查询,所以像这样:
SELECT
f.Name,
f.Age,
f.Gender,
ei1.Skills AS Skills_1,
ei2.Skills AS Skills_2,
ei1.Level AS Level_1,
ei2.Level AS Level_2
FROM
((Fact AS f
LEFT JOIN (
SELECT Name, Skills FROM ExtraInfo
UNION
SELECT Name, Skills FROM ExtraInfo_2) AS q ON q.Name = f.Name))
LEFT JOIN ExtraInfo AS ei1 ON ei1.Name = f.Name AND ei1.Skills = q.Skills)
LEFT JOIN ExtraInfo_2 AS ei2 ON ei2.Name = f.Name AND ei2.Skills = q.Skills
(MS Access 的语法可能不是 100%,但应该接近这个?)
如果您的数据确实如其所见,而您有时只是在“额外信息”中为某些人提供了更多行,那应该没问题。
【讨论】:
嘿,理查德,我真的很感谢您的长而完整的回答!我试过了,我不断收到以下错误:“查询表达式'q.Name = f.Name LEFT JOIN ExtraInfo ei1 ON ei1.Name = f.Name'中的语法错误(缺少运算符)。”你是否偶然知道问题?如果我跳过最后两个左连接,我将获得正确数量的技能,但它们不是每个来源(每个表)。 是的,我感觉 Access 不喜欢那种语法,我会四处寻找,看看能不能找到一个副本在某个地方旋转... 如果您有时间找到一些东西,那将是完美的,非常感谢!顺便说一句,你的回答很棒,谢谢!到目前为止,我只是尝试了不同的连接变体(左或内)但是我一直得到错误的映射 我猜这可能是很多事情,可能是因为Name
是保留字,或者可能是 Access 需要 AS
语句的事实(所以我将此添加到我上面的回答)?我找到了一个与此类似的示例的链接,所以这可能值得检查吗? dba.stackexchange.com/questions/73659/…
在 MS Access 中,多个 JOIN
子句需要在配对表周围加上括号。【参考方案2】:
也许你可以试试这样的:
SELECT
t4.Name,
t4.Age,
t4.Gender,
t4.Skills AS Skills_1,
t4.Level AS Level_1,
ei2.Skills AS Skills_2,
ei2.Level AS Level_2
FROM (
SELECT t3.Name, t3.Age, t3.Gender, ei1.Skills, ei1.Level, t2.Skills AS SkillsAll
FROM (
SELECT t1.*, t2.Skills
FROM Fact t1 INNER JOIN (
SELECT Name,Skills FROM ExtraInfo
UNION
SELECT Name,Skills FROM ExtraInfo_2
) t2 ON t1.Name=t2.Name
) t3 LEFT JOIN ExtraInfo ei1 ON t3.Name=ei1.Name AND t3.Skills=ei1.Skills
) t4 LEFT JOIN ExtraInfo_2 ei2 ON t4.SkillsAll=ei2.Skills AND t4.Name=ei2.Name;
【讨论】:
嘿R. Verbelis,我已经尝试过你的方法,但是这样你可能会错过一些技能,以防表3的技能比表2多,对吧?【参考方案3】:考虑对相关计数子查询进行匹配,但会占用大表:
SELECT agg1.Name, agg1.Age, agg1.Gender, agg1.Skills AS 1, agg1.Level AS Level_1,
agg2.Skills AS 2, agg2.Level AS Level_2
FROM
(SELECT f.Name, f.Age, f.Gender, e1.Skills, e1.Level,
(SELECT Count(*) FROM ExtraInfo sub
WHERE sub.Name = e1.Name AND sub.Skills <= e1.Skills) As rank
FROM Fact f INNER JOIN ExtraInfo e1 ON f.Name = e1.Name
) AS agg1
LEFT JOIN
(SELECT f.Name, f.Age, f.Gender, e2.Skills, e2.Level,
(SELECT Count(*) FROM ExtraInfo sub
WHERE sub.Name = e2.Name AND sub.Skills <= e2.Skills) As rank
FROM Fact f INNER JOIN ExtraInfo2 e2 ON f.Name = e2.Name
) AS agg2 ON (agg1.rank = agg2.rank) AND (agg1.Name = agg2.Name);
-- Name Age Gender Skills_1 Level_1 Skills_2 Level_2
-- Nordon 21 male Drawing Good Drawing Poor
-- Nordon 21 male Singing Poor Singing Good
-- Nordon 21 male Programming Good Programming Good
【讨论】:
哇,Parfait,你能解释一下这个基于计数的匹配吗?如果我错了,请纠正我,但如果使用内部连接,你会错过一些技能,以防其中一张表有更多条目。 子查询计算 ExtraInfo 和 ExtraInfo_2 表中每个不同 Skill 的排名 1、2、3按字母顺序。是的,以前的解决方案会遗漏大桌子的技能。请参阅使用LEFT JOIN
编辑以保留第二个表的所有行(如果第一个也可以这么大,请查看完全外连接)。
基本上你需要为你的输出调整技能的顺序,而不是技能本身。现在考虑您的需求,这是一个数据库设计问题。考虑结合 ExtraInfo 并从那里运行报告。
可能是一个愚蠢的问题,但你的排名是基于什么?你有计数,所以你计算它出现了多少次?我还是有点新,我可能在这里迷路了
如技能名称字母顺序所述。子查询和外部查询之间存在关联:sub.Skills <= e1.Skills
。您正在计算有多少行按字母顺序低于当前行的技能名称。以上是关于在 MS Access 中加入 3 个或更多表而不重复条目的主要内容,如果未能解决你的问题,请参考以下文章
如何使用内部/外部组合在 Access 中加入 4 个以上的表?