Просто к сведению, хорошее начало для вашего поста и пример ... всегда должны быть предоставлены ссылки на tableName.columnName (или alias.columnName), чтобы не допустить неоднозначности того, что другие не знают структуру вашей таблицы. Кроме того, вам действительно нужны только галочки для таких вещей, как зарезервированные слова или имена столбцов, в которых есть пробелы (в любом случае, никогда не такие).
Из моего прочтения ваш вопрос и примеры таблиц T1 и T2 ... T1 кажутся некой таблицей поиска и имеют идентификаторы и описания, связанные с указанными идентификаторами. Ваша таблица T2, по-видимому, является таблицей, основанной на деталях / транзакциях, и может иметь или не иметь фактическое требование, поэтому вы всегда хотите включать эти записи без специального требования.
Если это так, звучит так, будто вам нужны «все подробные записи, которые имеют некоторое условие НЕЗАБЫВАЕМОГО идентификатора соответствия, найденного в таблице поиска». Если это верно, вы будете искать
Select
T2.T1_ID,
coalesce( T1.Statement, '' ) StatementFromT1Table
from
SomeMainTable T2
LEFT JOIN SomeLookupTable T1
on T2.T1_ID = T1.T1_ID
where
T2.T1_ID = SomeIdParameterValue
AND ( T1.T1_ID is NULL
OR T1.Statement = SomeOtherParameterValue )
Соединение между таблицами. Я всегда стараюсь сначала перечислить левую таблицу, затем сделать отступ для правой таблицы, и мое условие ВКЛ показывает left.column = right.column, чтобы вы всегда видели взаимосвязь и то, как таблица A попадает в таблицу B (и вкладывается больше, когда в игру вступают другие объединения).
Различие между (INNER) JOIN и LEFT JOIN состоит в том, что (INNER) JOIN ТРЕБУЕТ запись, которая всегда совпадает в обеих таблицах. LEFT JOIN означает, что я хочу, чтобы все данные из таблицы на левой стороне НЕЗАВИСИМО от фактического соответствия в правой таблице.
Итак, на данный момент я сначала получаю все из таблицы псевдонимов T2 независимо от ответа в псевдониме T1. Теперь, как бороться с нулевым значением идентификатора замечаний. Если ноль означает, что вы ЗНАЕТЕ, что в T1 совпадения не будет, то вы можете просто сказать, что я хочу, чтобы все записи на стороне T2 были, если сторона T1 равна NULL ... Но вы также заботитесь о конкретном утверждении, следовательно, ИЛИ в скобках тест.
Первая часть где - это если вы специально искали все значения T1_ID = некоторого значения, так что это основной параметр и применимо только к стороне T2 ... вы определяете сторону T1 через AND (нулевой или другой критерий равенства) условие.
Если у вас есть некоторые конфиденциальные данные, можно рандомизировать / предоставлять образцы данных, но наличие реальной ссылки / контекста имени таблицы поможет нам лучше понять, чего вы пытаетесь достичь. Неоднозначность в именах таблиц и столбцах не помогает нам понять и может иметь лучшие решения для запросов, имеющие лучшее понимание.
Если я рядом и вам нужны дополнительные разъяснения, пожалуйста, сообщите и / или отредактируйте исходный пост с дополнительными образцами данных и окончательным выводом ... такими как параметры, которые также фильтруются.
РАЗЪЯСНЕНИЕ ПОЧТЫ.
По вашим комментариям, вот пояснения ...
"SomeMainTable T2" - это фактически действительное имя таблицы в вашей базе данных, а "T2" - это ссылка на ALIAS. Представьте, что ваша таблица называется «SomethingReallyLongDetail». Вы бы предпочли написать свой запрос что-то вроде
select
SomethingReallyLongDetail.Column1,
SomethingReallyLongDetail.Column7,
SomethingReallyLongDetail.Column20
from
SomethingReallyLongDetail
OR ...
select
SRL.Column1,
SRL.Column7,
SRL.Column20
from
SomethingReallyLongDetail SRL
В этом случае я использовал псевдоним "SRL", чтобы легче соотносить имя таблицы с аббревиатурой / сокращением по сравнению с необходимостью вводить длинное значение снова и снова, а затем иметь больше шансов набрать ошибки. Просто для удобства чтения, предоставляя ссылку "псевдоним" в запросе. Итак, я не знал вашего АКТУАЛЬНОГО имени таблицы, поэтому я составил его, но использовал ссылки "T1" и "T2", чтобы оставаться в соответствии с вашим исходным сообщением.
Далее, COALESCE (). Поскольку этот запрос выполняет LEFT-JOIN, правая таблица может (или нет) фактически иметь совпадение записей по идентификатору, поскольку, как вы знаете, не всегда может существовать. Так как я пытался извлечь столбец «Statement» из этой второй таблицы (псевдоним T1), это описание могло бы быть NULL, которое вы, вероятно, не хотели бы показывать в любом виде вывода. Чтобы предотвратить это, COALESCE () говорит, дайте мне значение из первого параметра в списке ... Если это значение равно нулю, дайте мне второе значение. В этом случае второе значение - просто пустая строка.
Параметры в запросе. Ваш исходный запрос имел ссылку на XXX и YYY, например, вы знали о конкретном значении T1.ID, которое вы хотите сузить до извлечения, но другое значение YYY как часть утверждения. Итак, место, где у вас был «XXX», я просто поместил здесь заполнитель, чтобы вы могли применить / указать любую ценность, которую вы конкретно искали. Точно так же для вашего значения "YYY", другой заполнитель для этого. Просто замените критерии, которые вы искали.
Наконец, это и часть предложения where. Это для условия LEFT-JOIN. Поскольку вы ЗНАЕТЕ, что не все записи будут иметь совпадение во вторичной таблице "T1", с помощью LEFT JOIN будет найден идентификатор и ИМЯ значение, или не будет значения и, следовательно, NULL.
Если нет подходящей записи, вы никогда не сможете сравнить какую-либо строку, int, date, что угодно со столбцом, поскольку он будет нулевым. Итак, я делаю
(T1.T1_ID IS NULL -- as in there was no match
OR T1.Statement = SomeOtherParameterValue ) -- there WAS a match, and I only want where the statement equals a given value.
Согласно вашим комментариям и результатам примера ваш запрос ДОЛЖЕН быть упрощен до ...
Select
T2.ID,
T2.T1_ID,
T2.Requirement,
coalesce( T1.Statement, '' ) StatementFromT1Table
from
T2
LEFT JOIN T1
on T2.Requirement = T1.T1_ID
where
T2.Requirement = 0
OR T1.T1_ID IS NOT NULL
В вашем случае, окончательный ответ ... Я хочу, чтобы все записи, в которых нет требования (таким образом, = 0), ИЛИ запись имеет совпадение в таблице T1 (таким образом, T1.T1_ID НЕ НУЛЬ)