访问3张桌子的完全联接

时间:2018-08-27 12:02:38

标签: sql ms-access ms-access-2010 full-outer-join

我正在尝试使用MS访问中的3个表执行完全外部联接,但是问题是访问不支持它。

我尝试使用3个左连接来做到这一点,但是在某些情况下我得到了重复的结果。

我正在尝试连接名称和日期在所有3个表中都相同的数据,

我的查询看起来像这样:

 SELECT
    a.date, a.name, a.whatewer,
    b.date, b.name, b.whatewer,
    c.date, c.name, c.whatewer

    FROM (a LEFT JOIN b ON a.date = b.date AND a.name = b.name)
    LEFT JOIN c ON c.date = a.date AND c.name = a.name

 UNION

 SELECT
    a.date, a.name, a.whatewer,
    b.date, b.name, b.whatewer,
    c.date, c.name, c.whatewer

 FROM (b LEFT JOIN a ON a.date = b.date AND a.name = b.name)
 LEFT JOIN c ON c.date = a.date AND c.name = a.name


SELECT
   a.date, a.name, a.whatewer,
   b.date, b.name, b.whatewer,
   c.date, c.name, c.whatewer

FROM (c LEFT JOIN a ON a.date = c.date AND a.name = c.name)
LEFT JOIN b ON c.date = b.date AND c.name = b.name

我得到的结果大部分是正确的,但是当表b和c中有数据但表a中没有数据时,我得到重复的结果。

我得到的结果不是全部都用一个单一的名称和日期连接,而是应该一行是来自表b的数据,然后是一行来自b和c的组合数据。

如何获得这些不必要的结果?

谢谢!

编辑:

完整代码(名称不是英语,我希望您能充分理解以提供帮助):

SELECT
Nz (Nz (zajem.Datum, ak.Datum ), nk.Datum ) AS Datum,
Nz (Nz (zajem.Operater, ak.Operater ), nk.Operater ) AS Operater,
zajem.Skupni_cas_zajema AS [Skupni cas zajema (min)], 
zajem.Povprecni_cas_zajema_na_PZ AS [Povprecni cas zajema na PZ (min)], 
zajem.Stevilo_PZ AS [Stevilo zajetih PZ], 
zajem.Stevilo_poligonov AS [Stevilo poligonov], 

ak.Skupni_cas_zajema AS [Skupni cas AK (min)], 
ak.Povprecni_cas_zajema_na_PZ AS [Povprecni cas AK na PZ], 
ak.Stevilo_PZ AS [Stevilo PZ (AK)], 
ak.Stevilo_poligonov AS [Stevilo poligonov (AK)],

nk.Skupni_cas_zajema AS [Skupni cas NK (min)], 
nk.Povprecni_cas_zajema_na_PZ AS [Povprecni cas NK na PZ], 
nk.Stevilo_PZ AS [Stevilo PZ (NK)], 
nk.Stevilo_poligonov AS [Stevilo poligonov (NK)]

FROM
(tabela_ves_zajem AS zajem LEFT OUTER JOIN tabela_vse_ak AS ak ON zajem.datum = ak.datum AND zajem.operater = ak.operater) LEFT OUTER JOIN tabela_vse_nk as nk ON nk.datum = zajem.datum AND nk.operater = zajem.operater


UNION


SELECT
Nz (Nz (zajem.Datum, ak.Datum ), nk.Datum ) AS Datum,
Nz (Nz (zajem.Operater, ak.Operater ), nk.Operater ) AS Operater,
zajem.Skupni_cas_zajema AS [Skupni cas zajema (min)], 
zajem.Povprecni_cas_zajema_na_PZ AS [Povprecni cas zajema na PZ (min)], 
zajem.Stevilo_PZ AS [Stevilo zajetih PZ], 
zajem.Stevilo_poligonov AS [Stevilo poligonov], 

ak.Skupni_cas_zajema AS [Skupni cas AK (min)], 
ak.Povprecni_cas_zajema_na_PZ AS [Povprecni cas AK na PZ], 
ak.Stevilo_PZ AS [Stevilo PZ (AK)], 
ak.Stevilo_poligonov AS [Stevilo poligonov (AK)],

nk.Skupni_cas_zajema AS [Skupni cas NK (min)], 
nk.Povprecni_cas_zajema_na_PZ AS [Povprecni cas NK na PZ], 
nk.Stevilo_PZ AS [Stevilo PZ (NK)], 
nk.Stevilo_poligonov AS [Stevilo poligonov (NK)]

FROM
(tabela_vse_ak AS ak LEFT OUTER JOIN tabela_ves_zajem AS zajem ON zajem.datum = ak.datum AND zajem.operater = ak.operater) LEFT OUTER JOIN tabela_vse_nk as nk ON nk.datum = zajem.datum AND nk.operater = zajem.operater


UNION

SELECT
Nz (Nz (zajem.Datum, ak.Datum ), nk.Datum ) AS Datum,
Nz (Nz (zajem.Operater, ak.Operater ), nk.Operater ) AS Operater,
zajem.Skupni_cas_zajema AS [Skupni cas zajema (min)], 
zajem.Povprecni_cas_zajema_na_PZ AS [Povprecni cas zajema na PZ (min)], 
zajem.Stevilo_PZ AS [Stevilo zajetih PZ], 
zajem.Stevilo_poligonov AS [Stevilo poligonov], 

ak.Skupni_cas_zajema AS [Skupni cas AK (min)], 
ak.Povprecni_cas_zajema_na_PZ AS [Povprecni cas AK na PZ], 
ak.Stevilo_PZ AS [Stevilo PZ (AK)], 
ak.Stevilo_poligonov AS [Stevilo poligonov (AK)],

nk.Skupni_cas_zajema AS [Skupni cas NK (min)], 
nk.Povprecni_cas_zajema_na_PZ AS [Povprecni cas NK na PZ], 
nk.Stevilo_PZ AS [Stevilo PZ (NK)], 
nk.Stevilo_poligonov AS [Stevilo poligonov (NK)]

FROM
(tabela_vse_nk AS nk LEFT OUTER JOIN tabela_ves_zajem AS zajem ON zajem.datum = nk.datum AND zajem.operater = nk.operater) LEFT OUTER JOIN tabela_vse_ak as ak ON nk.datum = ak.datum AND nk.operater = ak.operater;

我正在使用nz(nz(zajem.datum ....仅选择一个日期。

Data sample

所有其他表几乎相同,它们包含特定日期完成的任务的统计数据,每个表包含不同的任务。我需要显示某个用户(“操作员”)一天中的所有数据。

我尝试了第一个答案,但是在以一种很好的形式呈现数据时遇到了问题。

谢谢。

1 个答案:

答案 0 :(得分:2)

首先生成ID列表。然后使用left join

select . . . 
from (((select name, date from a
        union -- on purpose to remove duplicates
        select name, date from b
        union -- on purpose to remove duplicates
        select name, date from b
       ) nd left join
       a
       on a.name = nd.name and a.date = nd.date
      ) left join
      b
      on b.name = nd.name and b.date = nd.date
     ) left join
     c
     on c.name = nd.name and c.date = nd.date;