Левое соединение возвращает строки внутреннего соединения плюс несопоставленные строки левой таблицы, расширенные нулями. Если вы считаете, что хотите левое соединение, вам нужно определить связанное внутреннее соединение. Здесь вы, кажется, не знаете таблицы и условия. Но вы, кажется, по крайней мере хотите строки для каждой возможной пары студент-данные; действительно, для каждой комбинации (student_id, name) & (data_id, description). Так что те должны быть в левой таблице. Кроме того, оценка столбца равна нулю, поэтому, вероятно, она связана с правильной таблицей. Может быть, вы хотите:
select *
from students
natural join data
left natural join grade
Я выбрал этот запрос, потому что он (без нулей в общих столбцах и без повторяющихся строк):
/* rows where
student [student_id] has name [name]
and term [data_id] has description [description]
and (student [student_id] got grade [grade] in term [data_id]
or not exists grade [student [student_id] got grade [grade] in term [data_id]]
and [grade] is null
)
/*
Sqlite левое соединение составных клавиш
Хотя ограничения говорят нам кое-что о результате запроса, они не нужны для запроса. Требуется критерий членства результата запроса, то есть его предикат (характеристика) . Который в данном случае я дал в этом коде комментарий. Обратите внимание, как он построен из критериев / предикатов базовых таблиц:
natural join
содержит строки, удовлетворяющие and
критериев / предикатов его таблиц.
left natural join
содержит строки, удовлетворяющие and
критерия членства его левой таблицы с определенным or
с использованием критерия / предиката правой таблицы и условия, что каждый столбец уникален для правой таблицы is null
.
Есть ли эмпирическое правило для построения запроса SQL из понятного человеку описания? .
(Если столбцы description
& name
имеют одно и то же имя, вам придется либо переименовать его перед natural join
, либо использовать inner join
using (student_id, data_id)
. Но, опять же, это может возникнуть из-за составления соответствующего сказуемое.)