# Datenbank Join



## Kenan89 (11. Mai 2012)

Hallo,

heute mache ich meine ersten Schritte mit Joins.

Also ich habe zur Übung Newsletter in Java EE geschrieben.

Es funktioniert so:

Links sieht man die Themen(z.b. Spaß und Arbeit), auf die man klicken kann. Klickt man ein Thema an, sieht man, welche Einträge darin gespeichert sind, in der mitte des Bildschirms.

Die Autoren sind in einer Tabelle namens
"ID" "Autor"

Die Themen sind in einer Tabelle namens 
"Themen"
"ID" "Thema" "AutorID" 
(AutorID ist der Fremdschlüssel)

Die Einträge sind in einer Tabelle namens 
"Einträge"
"ID" "Eintrag" "Autor" "ThemenID"
(ThemenID ist der Fremdschlüssel)

Jetzt ist die Frage, wie man das programmiert, bzw. wie der SQL-Statement ist, um z.B. vom Autor XY alles Themen herauszufinden, die er angelegt hat.


Vielleicht?

```
select Thema from "Themen" where AutorID=2
```

Danke für eine hilfreiche Antwort.

EDIT:
Hmm... Ausserdem bin ich momentan mit den sogenannten Fremdschlüsseln beschäftigt. Aber brauche ich die überhaupt? Wenn ein Eintrag erstellt wird, dann darf z.B. das Feld Autor nicht leer sein. Das
heisst in meiner Tabelle Einträge trage ich einen Autor ein und kann dann  durch diese Zelle später nach allen Einträgen suchen, die Autor XY geschrieben hat.
Oder hat der Fremdschlüssel weitere Funktionen als nur Verbindungen zwischen Tabellen herzustellen?


----------



## maki (11. Mai 2012)

Kenan89 hat gesagt.:


> ...
> Vielleicht?
> 
> ```
> ...


Interessant, da wählst du einen Titel der "Datenbank Join" lautet, beschreibst eine Tabllenstruktur und deine mögiche Antwort lautet dann "select irgendwas from irgendwo where irgendwie", so ganz ohne Join... glaubst du denn selber dass das die richtige Antwort ist? 

Wenn du nur die ID als Kriterium wählst, wozu dann der Join?
Brauchst doch dann nur eine Tabelle abzufragen...
Ein Join wäre zB. sinnvoll wenn man vom Author Namen auf seine verfassten Bücher kommen möchte.


----------



## Kenan89 (11. Mai 2012)

> glaubst du denn selber dass das die richtige Antwort ist?


Nein 

Hmm... Ausserdem bin ich momentan mit den sogenannten Fremdschlüsseln beschäftigt. Aber brauche ich die überhaupt? Wenn ein Eintrag erstellt wird, dann darf z.B. das Feld Autor nicht leer sein. Das
heisst in meiner Tabelle Einträge trage ich einen Autor ein und kann dann durch diese Zelle später nach allen Einträgen suchen, die Autor XY geschrieben hat.
Oder hat der Fremdschlüssel weitere Funktionen als nur Verbindungen zwischen Tabellen herzustellen? 

Zum Beispiel in diesem Konstrukt komme ich eigentlich vollständig ohne Fremdschlüssel klar, denn in jeder Tabelle sind die ID`s der dazugehörigen Positionen in anderen Tabellen enthalten.





Ich will z.B. alle Einträge zum Thema *T2* vom User *XY*

PsyodoStatement schaut doch so aus:

*Wähle in Tabelle Einträge alle wo ThemaID: 2 und  UserID: 1
Um auch die Usernamen anzuzeigen sage ich noch:
*Wähle in Tabelle Themen Thema wo ID: 2
*Wähle in Tabelle Autor Name wo ID: 1


EDIT: Also ich frage deswegen, weil ich heute meine ersten Schritte Richtung Joins, Fremdschlüsseln und auch auf Abfragen über mehreren Tabellen hinweg mache.


----------



## ARadauer (11. Mai 2012)

mit einem join...

zb so..

select t.Thema from Themen t 
join Autoren a (on a.id = t.autorId)
where where a.Autor = 'Kenan'


----------



## maki (11. Mai 2012)

> Hmm... Ausserdem bin ich momentan mit den sogenannten Fremdschlüsseln beschäftigt. Aber brauche ich die überhaupt? Wenn ein Eintrag erstellt wird, dann darf z.B. das Feld Autor nicht leer sein.


Bevor du dich an Joins machst solltest du FKs vestanden haben, sind nämlich eine direkte Vorraussetzung dafür 



> Zum Beispiel in diesem Konstrukt komme ich eigentlich vollständig ohne Fremdschlüssel klar, denn in jeder Tabelle sind die ID`s der dazugehörigen Positionen in anderen Tabellen enthalten.


AuthorID und  ThemaID in Einträge sind Fremdschlüssel, dein zus. PK (ID) ist nutzlos, überflüssig und helfen dir kein bisschen, im Gegenteil 

Würde sagen du liest dir nochmals die Grundlagen zur Normalisierung (Theorie bis zur 3. Normalform reicht) und "referential integrity" durch, dann sollte dir einiges klarer werden.


----------



## ARadauer (11. Mai 2012)

Kenan89 hat gesagt.:


> Ich will z.B. alle Einträge zum Thema *T2* vom User *XY*


asso...

select e.Eintrag from Einträge e 
join Autoren a (on a.id = e.autorId)
join Themen t (on t.id = t.themenId)
where a.Autor = 'XY' and t.Thema = 'T2'



Kenan89 hat gesagt.:


> EDIT: Also ich frage deswegen, weil ich heute meine ersten Schritte Richtung Joins, Fremdschlüsseln und auch auf Abfragen über mehreren Tabellen hinweg mache.



warum probierst du es nicht einfach aus? es gibt 1000 anleitungen für joins...


----------



## Kenan89 (11. Mai 2012)

Fremdschlüssel und bis zur 3. Normalisierung hatte ich in der Schule.
Fremdschlüssel nimmt ja den Primärschlüssel  auf.
Zum Beispiel 1 Autor hat mehrere Texte.
1 Text kann mehreren Autoren zugeordnet werden.
In diesem Fall nimmt Tabelle Texte ID der AutorenTabelle als Fremdschlüssel auf.

Problem ist eben in der Schule haben wir das nie in der praxis programmiert und learning by doing ist ja sehr wichtig.



> warum probierst du es nicht einfach aus? es gibt 1000 anleitungen für joins...



Ich brauche den SQL Statement zum setzen eines Fremdschlüssels. Ich habe jetzt das Feld AutorenID in Tabelle Themen angelegt. Jetzt muss ich irgendwie mit alter column AutorenID diesen auf ein Fremdschlüssel umstellen(Momentan ist es nur ein integer).

EDIT:

```
ALTER TABLE "Themen"
                  ADD CONSTRAINT foreign_autor
                  FOREIGN KEY (autorID) REFERENCES "autor" (id);
```
Damit hat es geklappt einen Fremdschlüssel zu setzen? Ist das auch die korrekte und elegante Methode?


----------



## Kenan89 (11. Mai 2012)

So durch einen Fremdschlüssel gelangen schonmal keine falschen Daten mehr in die Tabelle.

Jetzt werde ich mich an Joins herantasten.

Das ist das Beispiel:




Ich will jetzt alle Themen des Autors XY anzeigen. Als Ergebnis müsste ich sehen: T1 und T3.



select t.Thema from Themen t
join Autor a (on a.id = t.AutorID);

Dieser Code klappt leider nicht.


----------



## Camino (11. Mai 2012)

Kenan89 hat gesagt.:


> select t.Thema from Themen t
> join Autor a (on a.id = t.AutorID);
> 
> Dieser Code klappt leider nicht.



"klappt nicht" ist aber eine komische Fehlermeldung.  Was kommt denn als Fehlermeldung? Keine Ahnung, ob ID != id ein fehler sein könnte...


----------



## SlaterB (11. Mai 2012)

gibt es eine Fehlermeldung?
welche Datenbank?

es gibt diverse Syntax-Varianten, hast du außer hier im Forum auch ein Tutorial oder Lehrbuch, nach dem du dich richtest?
SQL INNER JOIN Keyword

allgemeiner Tipp:
Java-Klassen und hier DB-Tabellen und ähnliches in Einzahl benennen, Thema statt Themen usw.,
warum hast du Autor und nicht Autoren? dieser gar Mischmasch ist noch schlimmer als alles Mehrzahl


----------



## Camino (11. Mai 2012)

Kenan89 hat gesagt.:


> select t.Thema from Themen t
> join Autor a (on a.id = t.AutorID);



Nimm doch mal die Klammern weg...


----------



## ARadauer (11. Mai 2012)

> Dieser Code klappt leider nicht.


wtf... was mach ich  mir eigentlich gedanken... 
naja habs jetzt nicht ausprobiert... "(on" schreib halt "on (" das sollte gehen...
nimm dir halt 5 minuten zeit dich mit meiner lösung zu beschäftigen...


----------



## Kenan89 (11. Mai 2012)

Aradauer deine Lösung klappt danke. Es kommen aber bestimmt bald neue Fragen


----------



## Kenan89 (11. Mai 2012)

> User
> id  name
> 1   Kenan
> 2   Hans
> ...



So, wenn ich jetzt alle Einträge, die dazugehörigen Namen, und das dazugehörige Thema ausgeben will, wie muss ich da vorgehen?


```
select u.name, t.thema, e.text
from "Einträge" as e
```
Wie geht es weiter?


----------



## SlaterB (11. Mai 2012)

du brauchst offensichtlich alle drei Tabellen, wie man das als Join formulieren kann, kannst du ausprobieren oder irgendwo nachschlagen,
immer geht alle Tabelle mit Komma aufzulisten und dann im WHERE gleiche Ids zu verlangen


----------



## Kenan89 (16. Mai 2012)

Hmm, ich blicke immer noch nicht so richtig durch. Zwischen 2 Tabellen kann ich joinen.
Aber bei 3 wird es schon komplexer.

Sagen wir ich möchte aus Tabelle Einträge alle Einträge des Users "Muster"(autorid 1) zum Thema "Freizeit".

Meine Vorgehensweise:


> select t.thema, u.user, e.text
> from "eintraege" as e
> join "themen" as t
> join "user" as u
> ...



Und da hänge ich... Wie geht es da weiter?


----------



## SlaterB (16. Mai 2012)

wie die Join-Syntax wer weiß wo aussieht, hat mich persönlich noch nie interessiert,
wenn man keine Spezialsituationen wie 'auch ein Ergebnis-Eintrag wenn gar kein Verbindungselement vorhanden ist' hat,
dann braucht man diese unbekannten Join-Schlüsselwörter überhaupt nicht,

ganz normal listet man alle Tabellen hintereinander auf:
FROM X x, Y y, Z z

und verknüpft sie passend:
WHERE x.idA = y.idA and y.idB = z.idB


----------

