Нормальный JOIN ... ON ...
синтаксис хорошо известен. Но также возможно расположить ON
предложение отдельно от того, JOIN
которому оно соответствует. Это то, что редко встречается на практике, не встречается в руководствах, и я не нашел ни одного веб-ресурса, который бы даже упоминал, что это возможно.
Вот скрипт, с которым можно поиграть:
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 выглядит нормально. q2 и q3 имеют эти необычные положения ON
пункта.
Этот сценарий не обязательно имеет большой смысл. Мне было трудно придумать значимый сценарий.
Так что же означают эти необычные синтаксические паттерны? Как это определяется? Я заметил, что не все позиции и заказы по двум ON
пунктам разрешены. Каковы правила, регулирующие это?
Кроме того, это когда-нибудь хорошая идея, чтобы писать такие запросы?