SQL-Abfrage mit Querverweisen

chgs2013

Aktiver Benutzer
Beiträge
37
Hallo,

bin neu im Forum, da ich Hilfe suche, bei der Erstellung einer SQL-Abfrage.

Ich arbeite mich erst in SQL ein, daher habe ich nur Verständnis für die einfachsten Funktionen.

Wie man einzelne Werte einer Spalte von Tabellen ausliest, ist soweit kein Problem, nur sobald
ich dann Werte in verschiedenen Tabellen vergleichen muss um eine Spalte auszulesen, scheiterts bei mir.

Aufgabenstellung:
Ausgabe des "Lagernamens" und "Lagerortes im entsprechenden Lager", wenn Artikelnummer "BSK-LT"


Folgendes habe ich vor, ich habe Artikel in einer Tabelle (tArtikel), jeder Artikel hat natürlich
eine "Artikelnummer (cArtNr)" und eine SQL interne Identnummer "kArtikel".

Soweit so gut, diese Identnummer "kArtikel" ist nun in einer anderen Tabelle (tArtikelLagerOrt) zu finden,
in dieser Tabelle werden nun 2 weitere angaben gemacht.
1.) Angabe des Lagers "kLager"
2.) Angabe des Lagerorts im Lager "kLagerOrt"

Um die Ausgabe des Lagernamens zu erhalten, muss man nun in der Tabelle "tLager" den Namen "cName" abfragen,
anhand dem Querverweis "kLager".
Ähnlich läuft es beim Lagerort vom Lager, hier muss man in der Tabelle "tLagerOrt" den Namen "cName" abfragen,
anhand des Querverweises "kLagerOrt" und "kLager".

Ich hoffe es kann mir jemand helfen, anbei auch Bilder.

Vielen Dank vorab.

image002.jpg

image001.jpg

image004.jpg

image003.jpg
 
Werbung:

ukulele

Datenbank-Guru
Beiträge
4.637
Da gibt es viele Wege, dies hier ist einer davon:
Code:
SELECT    tArtikelLagerOrt.kLager,
        tLager.cName,
        tArtikelLagerOrt.kLagerOrt,
        tLagerOrt.cName
FROM    tArtikelLagerOrt
LEFT JOIN tLager ON tArtikelLagerOrt.kLager = tLager.kLager
LEFT JOIN tLagerOrt ON tArtikelLagerOrt.kLagerOrt = tLagerOrt.kLagerOrt
WHERE    kArtikel = (    SELECT    kArtikel
                        FROM    tArtikel
                        WHERE    cArtNr = 'BSK-LT' )
Natürlich gibt es Dinge zu beachten wenn du z.B. nicht sicher stellen kannst, ob die Schlüssel alle eindeutig sind oder die cArtNr eventuell nicht eindeutig ist. Das sollte aber eigentlich nicht der Fall sein.
 

akretschmer

Datenbank-Guru
Beiträge
9.520
Hallo,

bin neu im Forum, da ich Hilfe suche, bei der Erstellung einer SQL-Abfrage.

Ich arbeite mich erst in SQL ein, daher habe ich nur Verständnis für die einfachsten Funktionen.

Wie man einzelne Werte einer Spalte von Tabellen ausliest, ist soweit kein Problem, nur sobald
ich dann Werte in verschiedenen Tabellen vergleichen muss um eine Spalte auszulesen, scheiterts bei mir.

Aufgabenstellung:
Ausgabe des "Lagernamens" und "Lagerortes im entsprechenden Lager", wenn Artikelnummer "BSK-LT"


Folgendes habe ich vor, ich habe Artikel in einer Tabelle (tArtikel), jeder Artikel hat natürlich
eine "Artikelnummer (cArtNr)" und eine SQL interne Identnummer "kArtikel".

Soweit so gut, diese Identnummer "kArtikel" ist nun in einer anderen Tabelle (tArtikelLagerOrt) zu finden,
in dieser Tabelle werden nun 2 weitere angaben gemacht.
1.) Angabe des Lagers "kLager"
2.) Angabe des Lagerorts im Lager "kLagerOrt"

Um die Ausgabe des Lagernamens zu erhalten, muss man nun in der Tabelle "tLager" den Namen "cName" abfragen,
anhand dem Querverweis "kLager".
Ähnlich läuft es beim Lagerort vom Lager, hier muss man in der Tabelle "tLagerOrt" den Namen "cName" abfragen,
anhand des Querverweises "kLagerOrt" und "kLager".

Was Du hast ist erst einmal ein schön normalisiertes Tabellendesign, so ist es schon mal richtig. Ich baue das mal nach, mit PG, aber das ist völlig egal:

Code:
test=# create table tartikel(cartnummer text, kartikel int primary key); 
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "tartikel_pkey" for table "tartikel"
CREATE TABLE                                                                                       
Time: 53,140 ms                                                                                    
test=*# create table tlager(cname text, klager int primary key);
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "tlager_pkey" for table "tlager"
CREATE TABLE                                                                                   
Time: 23,029 ms                                                                                
test=*# create table tartikellagerort(kartikel int references tartikel, klager int references tlager);
CREATE TABLE                                                                                          
Time: 5,100 ms                                                                                        
test=*# commit;                                                                                       
COMMIT

Das fülle ich jetzt mit Daten:

Code:
test=# insert into tartikel values ('artikel1',1);
INSERT 0 1
Time: 0,538 ms
test=*# insert into tartikel values ('artikel2',2);
INSERT 0 1
Time: 0,192 ms
test=*# insert into tartikel values ('artikel3',3);
INSERT 0 1
Time: 0,163 ms
test=*# insert into tlager values ('lager1',1);
INSERT 0 1
Time: 0,454 ms
test=*# insert into tlager values ('lager2',2);
INSERT 0 1
Time: 0,221 ms
test=*# insert into tartikellagerort values (2,1);
INSERT 0 1
Time: 15,305 ms
test=*# insert into tartikellagerort values (3,2);
INSERT 0 1
Time: 0,340 ms
test=*# commit;
COMMIT

Kontrolle:

Code:
test=*# select * from tartikel;
 cartnummer | kartikel
------------+----------
 artikel1   |        1
 artikel2   |        2
 artikel3   |        3
(3 rows)

Time: 0,172 ms
test=*# select * from tlager;
 cname  | klager
--------+--------
 lager1 |      1
 lager2 |      2
(2 rows)

Time: 0,154 ms
test=*# select * from tartikellagerort;
 kartikel | klager
----------+--------
        2 |      1
        3 |      2
(2 rows)

Um nun die Textbezeichnungen für die Lagerübersicht, also den Inhalt von 'tartikellagerort', zu erhalten, mußt Du diese Tabelle abfragen und die anderen Tabellen, die ja die Texte enthalten, links dazuJOINen. Die JOINS basieren jeweils auf den Schlüsselbeziehungen. Wenn man das erst einmal soweit verstanden hat, dann purzelt folgendes fast von selbst aus der Tastatur:

Code:
test=*# select a.cartnummer, l.cname from tartikellagerort lo left join tartikel a on (lo.kartikel=a.kartikel) left join tlager l on (lo.klager=l.klager);                                                                            
 cartnummer | cname                                                                                                
------------+--------                                                                                              
 artikel2   | lager1                                                                                               
 artikel3   | lager2                                                                                               
(2 rows)

Beschäftige Dich also nun mit dem JOIN-Befehl und seinen vielenVarianten.

Andreas
 

chgs2013

Aktiver Benutzer
Beiträge
37
Wow, ratzfatz ... schaut super aus, muss ich mal testen :)

Auch für mich zum Verständnis, man muss hier also mit JOIN-Anweisung arbeiten? Das habe ich mir gedacht, aber es gibt ja LEFT JOIN, RIGHT JOIN, JOIN, das hatte mich alles verwirrt!

Im ersten Schritt wird hier jetzt "selected"? Sprich ich muss hier alle abzufragenden Spalten aufführen? Warum nimmt man nun "FROM tArtikelLagerOrt", weil hier alle Infos enthalten sind???

Ich hab immer versucht Rückwärts aufzubauen, also erst kArtikel mit ArtNr zu bestimmen, anhand der die weiteren Tabellen abzugleichen *hust*
 

akretschmer

Datenbank-Guru
Beiträge
9.520
Wow, ratzfatz ... schaut super aus, muss ich mal testen :)

Auch für mich zum Verständnis, man muss hier also mit JOIN-Anweisung arbeiten? Das habe ich mir gedacht, aber es gibt ja LEFT JOIN, RIGHT JOIN, JOIN, das hatte mich alles verwirrt!

Man kann auch nur die Tabellen aufzählen und die JOIN-bedingungen in das WHERE packen. Läuft am Ende für die DB auf dasselbe hinaus, aber so ist es a) übersichtlicher und b) könnte man theoretisch dem Planner der DB (als dem Stück Programmcode, welches plant, wie die Abfrage am schnellsten auszuführen ist) auf diesem Wege noch quasi einen Hinweis mitgeben, wie er die Abfrage auszuführen hat (das geht aber, um mal vereinfacht zu sagen, nur mit weiteren Tricks und ist dann auch stark von der DB abhängig und soll jetzt nicht das Thema sein)

Im ersten Schritt wird hier jetzt "selected"? Sprich ich muss hier alle abzufragenden Spalten aufführen? Warum nimmt man nun "FROM tArtikelLagerOrt", weil hier alle Infos enthalten sind???

Ja, rein von der Logig her hast ja alle Infos, die gesucht sind, schon so stehen. Nur 'leider' als Verweis auf andere Tabellen, in denen die 'Details' stehen. Der LEFT JOIN ist vermutlich der am häufigsten angewandte JOIN.

Andreas
 

ukulele

Datenbank-Guru
Beiträge
4.637
Ich habe auch erstmal einen SELECT für kArtikel geschrieben und den rest dann drumherum gebaut. tArtikelLagerOrt ist natürlich die zentrale Tabelle, auch wenn die Informationen eigentlich später keinen interessieren.

Man muss hier nicht unbedingt die JOIN Syntax anwenden im Endeffekt ist es aber immer ein Join. Man kann auch erst die tArtikelLagerOrt auf die tArtikel joinen und auf den Subselect verzichten. Der LEFT JOIN ist sicherlich mit der am häufigsten genutzte aber hier mal noch das selbe als JOIN nur eben nicht als solcher geschrieben:
Code:
SELECT    tArtikelLagerOrt.kLager,
        tLager.cName,
        tArtikelLagerOrt.kLagerOrt,
        tLagerOrt.cName
FROM    tArtikelLagerOrt,
        tLager,
        tLagerOrt
WHERE    tArtikelLagerOrt.kArtikel = (    SELECT    kArtikel
                        FROM    tArtikel
                        WHERE    cArtNr = 'BSK-LT' )
AND        tArtikelLagerOrt.kLager = tLager.kLager
AND        tArtikelLagerOrt.kLagerOrt = tLagerOrt.kLagerOrt

Der Nachteil hierbei ist zunächst mal das, sobald ein Wert wie LagerOrt nicht vorhanden ist gar keine Daten angezeigt werden auch wenn vieleicht Lager gegeben ist.
 
Werbung:

chgs2013

Aktiver Benutzer
Beiträge
37
Klasse Forum, danke für die Erläuterungen!

OK, habe in Youtube paar Videos gefunden, mal schauen ob ich mir das mal so beibringen / vertiefen kann. :)

OK, durch die AND Anweisung muss dann immer etwas vorhanden sein, bei beiden ... ABER in meinem Fall soweit egal, da es ENTWEDER ein Lager MIT Lagerort gibt oder eben nicht :) ... macht ja auch in der Praxis Sinn :p
 
Oben