即使表2没有匹配记录,也从表1返回记录

时间:2020-01-02 18:37:47

标签: sql ms-access relational-database

我才刚刚开始学习SQL,所以如果这是一个非常基本的问题,请耐心等待,但这是我想要做的事情。

我正在编写查询以返回单个设备的历史记录。我从三个不同的表中提取,一个列出了每个设备(节点)的序列号,一个列出了每个设备是否每天都在线(节点状态),另一个列出了设备的位置。每个设备都已更改(“位置状态”)。

我想从“节点状态”表中提取每条记录,并且如果在“位置状态”表中也有一条记录,我也想将其转移过来。下面的查询将根据需要返回信息,但前提是两个表中都有匹配的更改记录。

        [Node Status].Online, Nodes.[Node Serial Number], [Node Status].Gateway,
        [Node Status].[Date Verified], [Node Location Status].[Location ID], 
        [Node Location Status].[Install/Remove], [Node Location Status].[Date of Action]
    FROM
        (Nodes 
    INNER JOIN 
        [Node Status] ON Nodes.NodeID = [Node Status].[Node Serial])
    INNER JOIN 
        [Node Location Status] ON (Nodes.NodeID = [Node Location Status].[Node Serial Number]) 
                               AND ([Node Status].[Date Verified] = [Node Location Status].[Date of Action])
    WHERE 
        ((Nodes.[Node Serial Number]) = [Enter node serial number]);

*注意:你们中很多人都建议LEFT JOIN,这似乎是正确的答案,但似乎我遗漏了重要的信息。我在Access中编写此代码,它显然不支持LEFT JOIN。

4 个答案:

答案 0 :(得分:1)

如果要将行保留在一个表中,即使其他表中没有匹配项,也要LEFT JOIN

因为您希望[Node Status]中的所有行都应该是第一个表。然后,所有后续联接都应为LEFT JOIN

SELECT ns.Online, n.[Node Serial Number], ns.Gateway,
       ns.[Date Verified], nls.[Location ID], 
       nls.[Install/Remove], nls.[Date of Action]
FROM [Node Status] ns LEFT JOIN
     Nodes n
     ON n.NodeID = ns.[Node Serial] LEFT JOIN
     [Node Location Status] nls
     ON n.NodeID = nls.[Node Serial Number] AND
        ns.[Date Verified] = nls.[Date of Action])
WHERE n.[Node Serial Number]) = [Enter node serial number];

请注意,我从FROM子句中删除了多余的括号,并添加了表别名。两者都使查询更易于阅读。

编辑:

MS Access不支持“常规” SQL语法。您必须对其进行一些调整:

SELECT ns.Online, n.[Node Serial Number], ns.Gateway,
       ns.[Date Verified], nls.[Location ID], 
       nls.[Install/Remove], nls.[Date of Action]
FROM ([Node Status] as ns LEFT JOIN
      Nodes as n
      ON n.NodeID = ns.[Node Serial]
     ) LEFT JOIN
     [Node Location Status] as nls
     ON n.NodeID = nls.[Node Serial Number] AND
        ns.[Date Verified] = nls.[Date of Action])
WHERE n.[Node Serial Number]) = [Enter node serial number];

答案 1 :(得分:1)

根据您的描述,我建议以下内容:

select
    ns.online,
    n.[node serial number],
    ns.gateway,
    ns.[date verified],
    nls.[location id],
    nls.[install/remove],
    nls.[date of action]
from
    (
        nodes n inner join [node status] ns on 
        n.nodeid = ns.[node serial]
    )
    left join [node location status] nls on
    ns.[node serial] = nls.[node serial number] and 
    ns.[date verified] = nls.[date of action]
where
    n.[node serial number] = [Enter node serial number]

鉴于用户正在从Nodes表中指定序列号,并且您声明要查看Node Status表中的所有条目,因此这应该是一个inner join,并且在left join表中有一个Node Location Status,以返回不存在值的空值。

请注意,别名nnsnls纯粹是为了节省键入内容。

我不确定为什么您认为MS Access不支持left join,因为它确实支持!

答案 2 :(得分:0)

我想您应该使用left join的意思,如果您希望在内部联接周围找到所需的o / p,请用left join

答案 3 :(得分:0)

使用LEFT JOIN代替INNER JOIN。您将从主表“节点”中获取所有记录,以及与其他表匹配的行