Если условие соединения выполняет преобразование данных, которое допустимо только для некоторых строк, но ваше условие where фильтрует строки по «действительным» строкам, это «безопасное» условие соединения?
Я считаю, что это не так, но я ни в коем случае не эксперт и просто пытаюсь понять. AFAIK оптимизатор может делать практически все, что захочет, если в конце дня все соединения будут выполнены и все условия в конечном итоге будут выполнены.
Я пытался это найти, но ничего конкретного не видел
SELECT *
FROM (SELECT 1 AS ID) a
JOIN (SELECT '1' AS ID,
'Y' AS FILTER
UNION
SELECT 'NOT_AN_INT' AS ID,
'N' AS FILTER) b
ON a.ID = CONVERT(INT, b.ID)
WHERE b.FILTER = 'Y'
SELECT *
FROM (SELECT 1 AS ID) a
JOIN (SELECT '1' AS ID,
'Y' AS FILTER
UNION
SELECT 'NOT_AN_INT' AS ID,
'N' AS FILTER) b
ON a.ID = CONVERT(INT, b.ID)
AND b.FILTER = 'Y'
Насколько я понимаю, условия соединения должны быть коммутативными при внутреннем соединении, и оба этих запроса должны быть эквивалентны друг другу. Однако второй взрывается из-за проблем приведения типов. Означает ли это, что это плохая практика, и вы должны сделать безопасное преобразование идентификатора a в varchar вместо идентификатора b в int? Или есть какая-то спецификация ANSI, гарантирующая, что это нормально?