SQL Server联接在其他表上不存在的位置

ako*_*oxi 4 sql sql-server inner-join

+-------------------+   +-------------------+   +---------------------+
|      Service      |   |       Asset       |   |     AssetService    |
+-------------------+   +-------------------+   +---------------------+
| Id   |    Name    |   | Id   |    Name    |   | AssetId | ServiceId |
|-------------------|   |-------------------|   |---------------------|
| 1    |  Service 1 |   | 1    |   Asset 1  |   |     1   |     1     |
| 2    |  Service 2 |   | 2    |   Asset 2  |   |     1   |     2     |
| 3    |  Service 3 |   | 3    |   Asset 3  |   |     2   |     2     |
+-------------------+   +-------------------+   |     2   |     3     |
                                                +---------------------+
Run Code Online (Sandbox Code Playgroud)

所以我有这些表。我想得到Services不在这样的AssetService地方AssetId = 1

+-------------------+
|      Service      |
| Id   |    Name    |
+-------------------+
| 3    |  Service 3 |
+-------------------+
Run Code Online (Sandbox Code Playgroud)

仅靠内/左/右连接可以做到这一点吗?因为我已经尝试过不同的内部联接组合,但是这种方法不起作用inner join Asset a on a.Id != as.AssetId。我尝试了左右联接。

有人可以帮我吗?

谢谢。

Cri*_*scu 5

我能想到的最简单的方法是:

select * from Service
where Id not in (
    select ServiceId
    from AssetService 
    where AssetId = 1);
Run Code Online (Sandbox Code Playgroud)

SQLFiddle链接

我认为无法使用inner join,因为那样只会检索符合某些条件的记录,而您正在寻找匹配的记录。

但是,left join正如Ctznkane525在他的回答中所示,可以这样做。

编辑

正如jarlh在评论中指出的那样,当子查询中存在null时,not in可能会导致令人惊讶的结果。所以,这是not exists版本:

select Id, Name
from Service s
where not exists (
    select *
    from AssetService a
    where AssetId = 1
    and ServiceId = s.Id);
Run Code Online (Sandbox Code Playgroud)

SQLFiddle链接


Elh*_*ani 5

您可以使用智能左联接仅从左表返回不匹配的行(服务)

SELECT S.Id, S.Name FROM [Service] S
LEFT JOIN ServiceAsset SA
ON S.Id = SA.ServiceId
WHERE SA.ServiceId IS NULL
Run Code Online (Sandbox Code Playgroud)

在此处输入图片说明

注意: INNER JOIN返回匹配的行,而您想要不匹配的行,则使用LEFT JOIN代替

  • 我希望我能两次赞成这个答案。这应该是公认的答案。 (2认同)