join on where

melmager

Erfahrenes Mitglied
ich versuche gerade join zu verstehen :)

wo ist eigendlich der unterschied zwischen on und where?
ich sehe da keinen -- muss aber sein sonst gäbe es on ja nicht

und dann habe ich gelesen das bei der where abfrage man darauf achten soll das die grösste einschränkung zu erst kommt aber in welcher reihenfolge wird die where abfrage denn duchgeforstet ?

ich baue gerade ein join mit drei tabellen und 100 million datensätze zu durchforsten kann
doch dauern ....

atab = artid , preis , ix > artikelzeile in der rechnung
btab = datum , ix > rechnung datum rechnungsnr
ctab = liefer , artid > lieferant hat artikel artid

(vereinfacht)

so sieht die abfrage aus:
select sum(atab.preis) from atab,btab,ctab where month(btab.datum)=1 and atab.ix=btab.ix and atab.artid=ctab.artid group by ctab.liefer

sollte den umsatz im januar von allen lieferanten anzeigen ;
ich gehe mal davon aus das die reihenfolge hinter from egal ist oder?
und die where solle so sein: ermittle alle rechnungen vom januar dann alle artikel in den ausgewählten rechnungen und dann dazu den lieferanten
ich hoffe atab.ix=btab.ix macht das gleiche wie btab.ix=atab.ix ??

hoffe auf etwas erhellung von einem sql guru :)
 
ich versuche gerade join zu verstehen :)

on wird bei left join gebraucht ; where bei join
unterschied : bei left join wird erst die on bedingung ausgewertet
dann verküpft -- bei join where genau umgekehrt
bedeutung: 100 join 100 = intern 10000 ergebnisse die dann mit where
abgeklappert werden ;
100 left join 100 = intern bei einer 1 zu 1 verküpfung 100 ergebnisse

...
mal sehen rest verstehe ich auch noch :)
 
JOINS - abfragen über mehrere tabellen hinweg

die gebräuchlichste benutzung von joins ist der sogenannte INNER JOIN. hierbei werden zwei tabellen anhand einer gemeinsamen spalte verknüpft (eine beziehung sollte also gegeben sein)

-- um in unserer datenbank herauszufinden, auf welche dateien ein user zugriff hat benötigt man folgenden befehl:
- select t_users.usname,t_access.acfilename from t_users inner join t_access on t_access.ac2us = t_users.usid order by t_users.usname asc

(was jetzt neu dazugekommen ist, ist die tatsache das vor spaltennamen die tabelle im sinne von tabelle.spaltenname angegeben wird. dies ist sinnvoll, wenn eine abfrage über mehr als eine tabelle geht und in unserem access beispiel sogar notwendig (access verweigert den dienst wenn die tabellennamen bei joins nicht vor der spalte angegeben werden - "Verknüpfungsausdruck nicht unterstützt", andere systeme wie zb der sql server benötigen diese notation nicht. unter umständen muss man sogar folgende notation verwenden: [TABELLENNAME].[SPALTENNAME])


um unsere beispieldatenbank anzusehen befindet sich in der tabelle T_ACCESS eine spalte namens AC2US. diese stellt einen sogenannten fremdschlüssel (foreign key) dar und verweist auf die T_USERS-Tabelle.

beispiel:

-- die tabelle t_users beinhaltet folgenden datensatz:
- 1 | Quentin | 123 | asdf@asdf.com (usid,usname,uspwd,usmail)

-- die tabelle t_access beinhaltet folgenden datensatz:
- 1 | nix.asp | 1 (acid,acfilename,ac2us)

dadurch, das ac2us die id 1 hat wissen wir schon, das diese User-ID dem user Quentin (also mir ;)) gehört. das obige beispiel mit dem innerjoin fügt diese zwei datensätze in einer abfrage zusammen!


hinweis: joins sind die gebräuchliche variante um tabellen in einer abfrage zu verknüpfen, es gibt aber auch noch eine andere möglichkeit auf die ich nicht näher eingehe *g*

-- das obige beispiel, ein klein wenig anders:
- select t_users.usname, t_access.acfilename from t_users, t_access where t_access.ac2us = t_users.usid


weitere joins:

-- mit INNER JOIN haben wir die tabellen zwar verknüpft, allerdings werden die einträge weggelassen, die keine beziehung zu der anderen tabelle haben. mit LEFT JOIN erhalten wir alle datensätze, auch wenn in der zweiten tabelle keine beziehung zur ersten besteht:
- select t_users.usname,t_access.acfilename from t_users left join t_access on t_access.ac2us = t_users.usid order by t_users.usname asc
-- jetzt wird auch ein datensatz zurückgegeben mit dem usernamen "HOLYFLY", allerdings bleibt die spalte ACFILENAME leer, da keine beziehung in der tabelle T_ACCESS zur tabelle t_USERS gegeben ist

-- wenn wir jetzt aber auch diejenigen datensätze selektieren wollen, die keine beziehung in der ersten tabelle zur zweiten tabelle herstellen, so verwenden wir RIGHT JOIN
- select t_users.usname,t_access.acfilename from t_users right join t_access on t_access.ac2us = t_users.usid order by t_users.usname asc
-- jetzt wird auch ein datensatz zurückgegeben ohne usernamen, allerdings steht in der spalte ACFILENAME der wert "keinuser.asp", da keine beziehung in der tabelle T_USERS zur tabelle t_ACCESS gegeben ist

aus meinem sql tutorial, das ich bald veröffentlichen werde ;)
 

Anhänge

  • db.zip
    16,4 KB · Aufrufe: 27

Neue Beiträge

Zurück