Frage an oracle11g, join, oracle, sql – Können Sie einen INNER JOIN ohne das Schlüsselwort ON haben?

15

Beim Debuggen in Oracle-Code bin ich auf folgende Abfrage gestoßen:

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

Ich bin verwirrt von der Linie:

INNER JOIN TPM_TASK

Ich habe noch keinen gesehenJOIN ohne eineON Klausel vor. Verwirrend ist auch die Zeile:

ON TPM_GROUP.GROUPID = TPM_GROUPTASKS.GROUPID

Dies scheint ein Zufall zu seinON Klausel ohne ÜbereinstimmungJOIN. Die Abfrage wird fehlerfrei ausgeführt und gibt eine Reihe von Daten zurück. Die Syntax ist also offensichtlich einwandfrei. Kann jemand etwas Licht ins Dunkel bringen, was genau hier los ist?

Als Randnotiz: Falls jemand nach einer Möglichkeit sucht, einen Join ohne ON-Klausel zu erstellen (wie ich es war), können Sie hierfür 'CROSS JOIN' verwenden, wodurch das kartesische Produkt zurückgegeben wird. Kt Mack

Deine Antwort

3   die antwort
4

wenn es Klammern drin hätte ...

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

aber da sie alle innere Verbindungen sind, stimme ich Lamaks Antwort zu.

20

das diese Syntax generiert hat, und war ziemlich durcheinander.

Offenbar,

FROM a 
     INNER JOIN b
     INNER JOIN c ON (b.id = c.id)
     ON (a.id = c.id)

entspricht einer verschachtelten Unterabfrage

FROM a
     INNER JOIN (SELECT <<list of columns>>
                   FROM b
                        INNER JOIN c ON (b.id=c.id)) c
             ON (a.id = c.id)
Ok, wenn diese Syntax die große Justin Cave durcheinander bringt, dann fühle ich mich definitiv nicht schlecht. Ich werde mit einigen einfacheren Fragen herumspielen, damit ich alles verstehe. Vielen Dank! Mike Christensen
@ NeilBarnwell - Es ist kein Tippfehler. Ich glaube, ich habe die Aliase so strukturiert, weilc In der ursprünglichen Abfrage wird dies sowohl als Tabelle als auch als Alias ​​für die Unterabfrage verwendet. Sie könnten dasselbe mit der Unterabfrage schreiben, die auf ausgerichtet istd und die Join-Bedingunga.id = d.id. Justin Cave
Vielen Dank. Ich wusste nicht einmal, dass du das kannst, denn woher weißt du, dass du das Alias ​​c oder die eigentliche Tabelle c meinst? Ich denke, es gibt eine wichtige Sache, bei der ich einen mehrdeutigen Referenzfehler erwarten würde. Neil Barnwell
Weißt du, ich habe das schon ewig angestarrt und kann es nicht verstehen. Ich denke, meine Verwirrung dreht sich um die Verwendung vonc als Tabelle und als Alias ​​für die Unterabfrage. Ist das ein Tippfehler oder eine typische Verwendung? Neil Barnwell
5

dass dies nur ein Problem bei der Bestellung Ihrer Anfrage ist (da gibt es nurINNER JOINs, die Reihenfolge ist eigentlich nicht so wichtig). Ich habe Ihre Anfrage umgestaltet und jetzt sieht es so aus:

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 

Macht es für dich jetzt mehr Sinn ?, tut es für mich.

Verwandte Fragen