Information ausblenden
Willkommen im Forum für alle Datenbanken! Registriere Dich kostenlos und diskutiere über DBs wie Mysql, MariaDB, Oracle, Sql-Server, Postgres, Access uvm

SQL-Abfrage mit Querverweisen

Dieses Thema im Forum "Microsoft SQL Server" wurde erstellt von chgs2013, 29 Januar 2013.

  1. chgs2013

    chgs2013 Aktiver Benutzer

    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
     
  2. ukulele

    ukulele Datenbank-Guru

    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.
     
  3. akretschmer

    akretschmer Datenbank-Guru

    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
     
  4. chgs2013

    chgs2013 Aktiver Benutzer

    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*
     
  5. akretschmer

    akretschmer Datenbank-Guru

    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)

    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
     
  6. ukulele

    ukulele Datenbank-Guru

    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.
     
  7. akretschmer

    akretschmer Datenbank-Guru

    Was man wiederum mit passenden Constraints verhindern kann ... NOT NULL.

    Andreas
     
  8. chgs2013

    chgs2013 Aktiver Benutzer

    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
     
Die Seite wird geladen...

Diese Seite empfehlen

  1. Diese Seite verwendet Cookies. Wenn du dich weiterhin auf dieser Seite aufhältst, akzeptierst du unseren Einsatz von Cookies.
    Information ausblenden