У вас есть INNER JOIN без ключевого слова ON?
Во время отладки в некоторый код Oracle я наткнулся на этот запрос:
SELECT TPM_TASK.TASKID FROM TPM_GROUP
INNER JOIN TPM_USERGROUPS ON TPM_GROUP.GROUPID = TPM_USERGROUPS.GROUPID
INNER JOIN TPM_TASK
INNER JOIN TPM_GROUPTASKS ON TPM_TASK.TASKID = TPM_GROUPTASKS.TASKID
INNER JOIN TPM_PROJECTVERSION ON TPM_TASK.PROJECTID = TPM_PROJECTVERSION.PROJECTID AND TPM_TASK.VERSIONID = TPM_PROJECTVERSION.VERSIONID
INNER JOIN TPM_TASKSTAGE ON TPM_TASK.STAGEID = TPM_TASKSTAGE.STAGEID
INNER JOIN TPM_PROJECTSTAGE ON TPM_PROJECTVERSION.STAGEID = TPM_PROJECTSTAGE.STAGEID
ON TPM_GROUP.GROUPID = TPM_GROUPTASKS.GROUPID
Меня смущает строка:
INNER JOIN TPM_TASK
Я еще не видел JOIN
без предложения ON
. Также запутанной является строка:
ON TPM_GROUP.GROUPID = TPM_GROUPTASKS.GROUPID
Это похоже на случайное предложение ON
без соответствия JOIN
. Запрос выполняется без каких-либо ошибок и возвращает кучу данных, поэтому очевидный синтаксис совершенно прав. Может кто-то пролить свет на то, что происходит здесь?
Ответы
Ответ 1
Маленький юниверс... Я наткнулся на инструмент, генерирующий этот синтаксис вчера, и был довольно запутан.
По-видимому,
FROM a
INNER JOIN b
INNER JOIN c ON (b.id = c.id)
ON (a.id = c.id)
эквивалентен вложенному подзапросу
FROM a
INNER JOIN (SELECT <<list of columns>>
FROM b
INNER JOIN c ON (b.id=c.id)) c
ON (a.id = c.id)
Ответ 2
Я думаю, что это всего лишь проблема упорядочения вашего запроса (поскольку есть только INNER JOIN
s, порядок их на самом деле не так важен). Я запросил ваш запрос, и теперь он выглядит так:
SELECT TPM_TASK.TASKID
FROM TPM_GROUP
INNER JOIN TPM_USERGROUPS
ON TPM_GROUP.GROUPID = TPM_USERGROUPS.GROUPID
INNER JOIN TPM_GROUPTASKS
ON TPM_GROUP.GROUPID = TPM_GROUPTASKS.GROUPID
INNER JOIN TPM_TASK
ON TPM_TASK.TASKID = TPM_GROUPTASKS.TASKID
INNER JOIN TPM_PROJECTVERSION
ON TPM_TASK.PROJECTID = TPM_PROJECTVERSION.PROJECTID
AND TPM_TASK.VERSIONID = TPM_PROJECTVERSION.VERSIONID
INNER JOIN TPM_TASKSTAGE
ON TPM_TASK.STAGEID = TPM_TASKSTAGE.STAGEID
INNER JOIN TPM_PROJECTSTAGE
ON TPM_PROJECTVERSION.STAGEID = TPM_PROJECTSTAGE.STAGEID
Теперь у вас есть больше смысла?, это со мной.
Ответ 3
Это выглядело бы хорошо, если бы там были круглые скобки...
SELECT TPM_TASK.TASKID
FROM
TPM_GROUP
INNER JOIN TPM_USERGROUPS ON TPM_GROUP.GROUPID = TPM_USERGROUPS.GROUPID
INNER JOIN (
TPM_TASK
INNER JOIN TPM_GROUPTASKS ON TPM_TASK.TASKID = TPM_GROUPTASKS.TASKID
INNER JOIN TPM_PROJECTVERSION ON TPM_TASK.PROJECTID = TPM_PROJECTVERSION.PROJECTID
AND TPM_TASK.VERSIONID = TPM_PROJECTVERSION.VERSIONID
INNER JOIN TPM_TASKSTAGE ON TPM_TASK.STAGEID = TPM_TASKSTAGE.STAGEID
INNER JOIN TPM_PROJECTSTAGE ON TPM_PROJECTVERSION.STAGEID = TPM_PROJECTSTAGE.STAGEID
) ON TPM_GROUP.GROUPID = TPM_GROUPTASKS.GROUPID
но поскольку все они являются внутренними, я согласен с ответом Ламака.