A JOIN ... ON ...
sintaxe normal é bem conhecida. Mas também é possível posicionar a ON
cláusula separadamente da JOIN
que ela corresponde. Isso é algo que raramente é visto na prática, não encontrado nos tutoriais e não encontrei nenhum recurso da Web que até mencione que isso é possível.
Aqui está um script para brincar:
SELECT *
INTO #widgets1
FROM (VALUES (1), (2), (3)) x(WidgetID)
SELECT *
INTO #widgets2
FROM (VALUES (1, 'SomeValue1'), (2, 'SomeValue2'), (3, 'SomeValue3')) x(WidgetID, SomeValue)
SELECT *
INTO #widgetProperties
FROM (VALUES
(1, 'a'), (1, 'b'),
(2, 'a'), (2, 'b'))
x(WidgetID, PropertyName)
--q1
SELECT w1.WidgetID, w2.SomeValue, wp.PropertyName
FROM #widgets1 w1
LEFT JOIN #widgets2 w2 ON w2.WidgetID = w1.WidgetID
LEFT JOIN #widgetProperties wp ON w2.WidgetID = wp.WidgetID AND wp.PropertyName = 'b'
ORDER BY w1.WidgetID
--q2
SELECT w1.WidgetID, w2.SomeValue, wp.PropertyName
FROM #widgets1 w1
LEFT JOIN #widgets2 w2 --no ON clause here
JOIN #widgetProperties wp
ON w2.WidgetID = wp.WidgetID AND wp.PropertyName = 'b'
ON w2.WidgetID = w1.WidgetID
ORDER BY w1.WidgetID
--q3
SELECT w1.WidgetID, w2.SomeValue, wp.PropertyName
FROM #widgets1 w1
LEFT JOIN (
#widgets2 w2 --no SELECT or FROM here
JOIN #widgetProperties wp
ON w2.WidgetID = wp.WidgetID AND wp.PropertyName = 'b')
ON w2.WidgetID = w1.WidgetID
ORDER BY w1.WidgetID
q1 parece normal. q2 e q3 têm esses posicionamentos incomuns da ON
cláusula.
Esse script não faz necessariamente muito sentido. Foi difícil para mim inventar um cenário significativo.
Então, o que significam esses padrões incomuns de sintaxe? Como isso é definido? Percebi que nem todas as posições e pedidos das duas ON
cláusulas são permitidos. Quais são as regras que regem isso?
Também é uma boa ideia escrever consultas como essa?