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。我尝试了左右联接。
有人可以帮我吗?
谢谢。
我能想到的最简单的方法是:
select * from Service
where Id not in (
select ServiceId
from AssetService
where AssetId = 1);
Run Code Online (Sandbox Code Playgroud)
我认为无法使用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)
您可以使用智能左联接仅从左表返回不匹配的行(服务)
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代替