Вопрос по sql – Можно ли присоединиться к INNER без ключевого слова ON?

15

При отладке в некотором коде 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, Запрос выполняется без каких-либо ошибок и возвращает кучу данных, поэтому очевидно, что синтаксис совершенно корректен. Может ли кто-нибудь пролить свет на то, что здесь происходит?

Как примечание: если кто-то ищет, как СОЗДАТЬ объединение без предложения ON (как я), вы можете использовать для этого CROSS JOIN, который возвращает декартово произведение. Kt Mack

Ваш Ответ

3   ответа
20

генерирующий этот синтаксис, и был довольно обескуражен.

По всей видимости

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)
Хорошо, если этот синтаксис сбил с толку великую пещеру Джастина, то я определенно не чувствую себя слишком плохо. Я поэкспериментирую с некоторыми более простыми вопросами, поэтому я полностью понимаю. Благодарность Mike Christensen
Знаешь, я смотрю на это целую вечность и не могу понять. Я думаю, что мое замешательство связано с использованиемc как таблица и псевдоним для подзапроса. Это опечатка или типичное использование? Neil Barnwell
@ NeilBarnwell - это не опечатка. Мне кажется, я структурировал псевдонимы таким образом, потому чтоc в исходном запросе используется в качестве таблицы и псевдонима для подзапроса. Вы можете написать то же самое с подзапросом с псевдонимомd и условие соединенияa.id = d.id. Justin Cave
Благодарность. Я даже не знал, что вы могли бы сделать это, потому что откуда он знал, что вы имели в виду псевдоним c или фактическую таблицу c? Я предполагаю, что происходит приоритетная вещь, где я ожидал бы некоторую неоднозначную ошибку ссылки. Neil Barnwell
5

что это только проблема заказа вашего запроса (так как есть толькоINNER JOINs, их порядок не так уж важен). Я изменил ваш запрос, и теперь он выглядит так:

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 

Имеет ли это для тебя больше смысл

4

если бы там были круглые скобки ...

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

но поскольку они все являются внутренними соединениями, я согласен с ответом Ламака.

Похожие вопросы