加入3个或更多表而不复制MS Access中的条目

时间:2018-03-12 12:19:56

标签: sql ms-access join

我目前正在练习我的访问技巧,并感谢您对以下问题的任何帮助。

问题在于我试图将3个表合并为一个。我使用其中一个作为主表(事实表),其他2个表有关于事实的额外信息,但信息是相同的但来自不同的来源。你可以看到下面的一个例子(我仍在搞清楚) stackoverflow所以我很抱歉这个可怜的造型)

事实表

Name     Age    Gender      
Nordon   21     male

ExtraInfo

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每个事实也有不同的条目数量。有没有办法很好地解决这个问题?

感谢所有帮助!

3 个答案:

答案 0 :(得分:0)

也许你可以尝试这样的事情:

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;

答案 1 :(得分:0)

有很多不同的方法可以做到这一点,但是使用INNER JOIN我会猜测你只是没有在技能的两个额外信息表之间包含一个链接名称?在这种情况下,这样的事情应该有效:

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

如果您在额外信息表中存在潜在的差距,那么您将需要使用LEFT JOIN,这变得更加棘手,因为在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%,但它应该接近这个?)

如果您的数据看起来非常真实,那么您有时会在" Extra Info"对某些人来说那应该没问题。

答案 2 :(得分:0)

考虑在相关计数子查询上进行匹配,但是具有大表的足迹:

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