Предложение where, фактически сделавшее ваш последний левый, соединяется с внутренним соединением.
Для исправления перемещения влево присоединиться к критериям фильтра к вступлению критериев
select d2.*
from Devices as d1
left outer join Links as l on d1.id in (l.device_id_1, l.device_id_2)
left outer join Devices as d2 on d2.id in (l.device_id_1, l.device_id_2)
and d2.id <> 398
where d1.id = 398;
гораздо менее элегантно, хотя общепринятым подходом было бы ...
select d2.*
from Devices as d1
left outer join Links as l on d1.id in (l.device_id_1, l.device_id_2)
left outer join Devices as d2 on d2.id in (l.device_id_1, l.device_id_2)
where d1.id = 398
and (d2.id <> 398 OR D2.ID is null)
Я вообще думаю, что об этом так ..
При использовании внешних соединений я обычно хочу исключить строки до того, как произойдет соединение, поэтому движку не нужно создавать такой большой декартов. Кроме того, на внешних соединениях нулевые записи я хочу вернуть. Однако, если я применил бы предел в предложении where, все нулевые записи, созданные из внешнего соединения, будут удалены, если я не буду учитывать также NULLS.
В этом случае, поскольку вы используете <> ... <> не может сравниться с нулевым значением, он будет исключать нужные записи, поскольку вы не можете использовать проверку равенства на нулевом значении.
1 = NULL возвращает NULL и 1 <> NULL возвращает NULL; таким образом, это не так.
Подведите d2.id <> 398 в качестве И условие к критерию соединения. Вы отрицаете левое соединение своим текущим подходом; по сути дела делая его внутренним соединением. Менее элегантный подход заключается в проверке нулевого значения на d2.id – xQbert
Похоже, вы могли бы сделать это только с помощью таблицы ссылок.Есть ли другие данные, которые вы хотите в таблице Устройства, отличные от id? – kbball