La JOIN ... ON ...
sintaxis normal es bien conocida. Pero también es posible colocar la ON
cláusula por separado de la JOIN
que corresponde. Esto es algo que rara vez se ve en la práctica, no se encuentra en los tutoriales y no he encontrado ningún recurso web que incluso mencione que esto es posible.
Aquí hay un script para jugar:
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 se ve normal. q2 y q3 tienen estas posiciones inusuales de la ON
cláusula.
Este script no necesariamente tiene mucho sentido. Fue difícil para mí idear un escenario significativo.
Entonces, ¿qué significan estos patrones de sintaxis inusuales? ¿Cómo se define esto? Noté que no todas las posiciones y órdenes para las dos ON
cláusulas están permitidas. ¿Cuáles son las reglas que gobiernan esto?
¿También es una buena idea escribir consultas como esta?