Ergebnis 1 bis 6 von 6

Thema: join über mehrere Tabellen mit auswahlkriterien oder begrenzung

  1. #1
    Crypi ist offline Erfahrener Benutzer
    Registriert seit
    28.12.2005
    Ort
    Hamburg
    Beiträge
    127

    Standard join über mehrere Tabellen mit auswahlkriterien oder begrenzung

    Hallo liebes Forum,

    ich habe mal wieder ein SQL-Problem.

    Ich habe eine Tabelle in der ich Stücklisten zusammenstelle.
    Zu jedem Eintrag in einer Stückliste gibt es einen Stammdatensatz.
    Also eine einfache n:m Beziehung.

    Zu jedem Stammdatensatz gibt es zwei Tabellen in denen Preisinformationen stehen KÖNNEN. Jeweils mit einem Datum und einer Einheit (Preis pro Stück, pro 100 Stück).

    stammdaten
    laufendenummer | name

    stueckliste
    laufendenummer_stammdaten | laufendenummer_stueckliste

    preis1
    laufendenummer_stammdaten | datum | preis | einheit

    preis2
    laufendenummer_stammdaten | datum | preis | einheit



    Jetzt möchte ich mir die Srücklisten ausgeben lassen und für jeden Eintrag auch gleich den aktuellesten Preis mit Einheit.
    Als Resultat sollte also sowas rauskommen, jeweils für jede Position eine Ergebniszeile die so aussieht:

    laufendenummer_stammdaten | preis | einheit | datum
    laufendenummer_stammdaten | preis | einheit | datum
    laufendenummer_stammdaten | preis | einheit | datum
    ...

    Der Preis kommt aus einer der beiden Tabellen, preis1 oder preis2, aus welcher bestimmt sich über das Datum.

    Wie kann ich das lösen.
    Ich finde keinen Ansatz.
    group by hilft mir nicht, oder?


    Ein weiterer Ansatz wäre, dass ich erstmal die beiden jeweils aktuellesten Preise aus den Tabellen entnehme und dann über das Programm, dass dahinter steht auswerten lasse welcher Preis stimmt.
    Dann bleibt aber noch die Frage, wie ich das Ergebnis eines Left Join über die Preistabellen auf eine Ergebniszeile pro Stammdatensatz begrenzen kann,wobei dann wieder das Datum ausschlaggebend ist.

    laufendenummer_stammdaten | preis1 | einheit1 | datum1 | preis2 | einheit2 | datum2
    laufendenummer_stammdaten | preis1 | einheit1 | datum1 | preis2 | einheit2 | datum2
    laufendenummer_stammdaten | preis1 | einheit1 | datum1 | preis2 | einheit2 | datum2
    ...



    Ich hoffe ihr habt eine Idee!

    Danke für eure Hilfe!
    Crypi

  2. #2
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von Crypi Beitrag anzeigen
    Hallo liebes Forum,

    ich habe mal wieder ein SQL-Problem.

    Ich habe eine Tabelle in der ich Stücklisten zusammenstelle.
    Zu jedem Eintrag in einer Stückliste gibt es einen Stammdatensatz.
    Also eine einfache n:m Beziehung.

    Zu jedem Stammdatensatz gibt es zwei Tabellen in denen Preisinformationen stehen KÖNNEN. Jeweils mit einem Datum und einer Einheit (Preis pro Stück, pro 100 Stück).

    stammdaten
    laufendenummer | name

    stueckliste
    laufendenummer_stammdaten | laufendenummer_stueckliste

    preis1
    laufendenummer_stammdaten | datum | preis | einheit

    preis2
    laufendenummer_stammdaten | datum | preis | einheit
    Könntest Du statt dem Roman vielleicht auch Copy&Paste-fähige SQL-Befehle zum Erstellen der Tabellen bringen?


    Jetzt möchte ich mir die Srücklisten ausgeben lassen und für jeden Eintrag auch gleich den aktuellesten Preis mit Einheit.
    Als Resultat sollte also sowas rauskommen, jeweils für jede Position eine Ergebniszeile die so aussieht:

    laufendenummer_stammdaten | preis | einheit | datum
    laufendenummer_stammdaten | preis | einheit | datum
    laufendenummer_stammdaten | preis | einheit | datum
    ...

    Der Preis kommt aus einer der beiden Tabellen, preis1 oder preis2, aus welcher bestimmt sich über das Datum.
    Wie bestimmt sich das, nach welcher Regel? Dies ist nicht klar.


    Wie kann ich das lösen.
    Ich finde keinen Ansatz.
    group by hilft mir nicht, oder?
    Nein, erst einmal mußt Du alle Deine Tabellen JOINen. Nach welcher Regel wird der Preis gezogen?




    Ich hoffe ihr habt eine Idee!
    Code:
    test=*# select * from stammdaten ;
     laufendenummer |   name
    ----------------+-----------
                  1 | stammdat1
                  2 | stammdat2
                  3 | stammdat3
    (3 rows)
    
    test=*# select * from stueckliste ;
     laufendenummer_stammdaten | laufendenummer_stueckliste
    ---------------------------+----------------------------
                             1 |                          1
                             2 |                          1
                             3 |                          1
    (3 rows)
    
    test=*# select * from preis1;
     laufendenummer_stammdaten |   datum    | preis | einheit
    ---------------------------+------------+-------+---------
                             1 | 2010-08-18 |   100 | Kilo
    (1 row)
    
    test=*# select * from preis2;
     laufendenummer_stammdaten |   datum    | preis | einheit
    ---------------------------+------------+-------+---------
                             3 | 2010-08-18 |   300 | Kilo
    (1 row)
    
    test=*# select sl.laufendenummer_stammdaten, coalesce(p1.preis,0) + coalesce(p2.preis,0) as preis, coalesce(p1.einheit,'') || coalesce(p2.einheit,'') as einheit from stueckliste sl left join preis1 as p1 on (sl.laufendenummer_stammdaten=p1.laufendenummer_stammdaten) left join preis2 p2 on (sl.laufendenummer_stammdaten=p2.laufendenummer_stammdaten);
     laufendenummer_stammdaten | preis | einheit
    ---------------------------+-------+---------
                             1 |   100 | Kilo
                             2 |     0 |
                             3 |   300 | Kilo
    (3 rows)

    Mal so als Anfang.


    Andreas, der grad das Firefox-Plugin 'All-Text' testet ...
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  3. #3
    Crypi ist offline Erfahrener Benutzer
    Registriert seit
    28.12.2005
    Ort
    Hamburg
    Beiträge
    127

    Standard

    vielen Dank für die schnelle Antwort!

    welcher Preis genommen wird, entscheidet sich darüber welches Datum aktueller ist.
    Wenn in preis1 ein Preis vom 18.08.2010 steht und in preis2 ein Preis vom 17.08.2010, dann soll der Preis aus preis1 genommen werden.

    Entschuldige bitte, ich werde zukünftig entsprechende copy&paste Beispiele erstellen!

    Ich habe dein Beispiel ausprobiert.
    Sobald bei mir in beiden Tabellen für den gleichen Stamdatensatz ein Preis steht, dann werden die werte addiert.


    An was ich eher dachte, war:

    Select p1.preis, p1.einheit, p2.preis, p2.einheit, sl.laufendenummer_stammdaten from stueckliste as sl
    left join preis1 as p1
    on p1.laufendenummer_stammdaten = sl.laufendenummer_stammdaten
    left join preis2 as p2
    on p2.laufendenummer_stammdaten = sl.laufendenummer_stammdaten
    order by p1.datum, p2.datum

    wobei jeweils nur der aktuellste Datensatz aus p1 und p2 genommen wird, so dass man garantiert pro Stücklisteneintrag nur eine Ergebniszeile erhält.
    Und wie man das einschränken kann, dass weiß ich nicht.

    Oder als Alternative, wo mir aber gänzlich der Ansatz fehlt, es wird bevor die Ergebniszeile gebildet wird verglichen welcher Datensatz, p1 oder p2, der aktuellste ist.

    Ich hoffe ich kann verständlich machen was ich meine!

    Crypi

  4. #4
    ads
    ads ist offline Super-Moderator
    Registriert seit
    08.02.2006
    Ort
    MD
    Beiträge
    4.020

    Standard

    Hast du die Möglichkeit, diese Datenbank noch umzudesignen?
    Das hört sich alles recht krank an.
    Xandrian: Kurz gesagt: Du hast ein falsches Konzept und willst nicht auf ads hören

    Jetzt NEU: PostgreSQL - Datenbankpraxis für Anwender, Administratoren und Entwickler

    PostgreSQL Service & Support

  5. #5
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von Crypi Beitrag anzeigen
    vielen Dank für die schnelle Antwort!

    welcher Preis genommen wird, entscheidet sich darüber welches Datum aktueller ist.
    Wenn in preis1 ein Preis vom 18.08.2010 steht und in preis2 ein Preis vom 17.08.2010, dann soll der Preis aus preis1 genommen werden.

    Entschuldige bitte, ich werde zukünftig entsprechende copy&paste Beispiele erstellen!

    Ich habe dein Beispiel ausprobiert.
    Sobald bei mir in beiden Tabellen für den gleichen Stamdatensatz ein Preis steht, dann werden die werte addiert.


    An was ich eher dachte, war:

    Select p1.preis, p1.einheit, p2.preis, p2.einheit, sl.laufendenummer_stammdaten from stueckliste as sl
    left join preis1 as p1
    on p1.laufendenummer_stammdaten = sl.laufendenummer_stammdaten
    left join preis2 as p2
    on p2.laufendenummer_stammdaten = sl.laufendenummer_stammdaten
    order by p1.datum, p2.datum

    wobei jeweils nur der aktuellste Datensatz aus p1 und p2 genommen wird, so dass man garantiert pro Stücklisteneintrag nur eine Ergebniszeile erhält.
    Und wie man das einschränken kann, dass weiß ich nicht.

    Oder als Alternative, wo mir aber gänzlich der Ansatz fehlt, es wird bevor die Ergebniszeile gebildet wird verglichen welcher Datensatz, p1 oder p2, der aktuellste ist.

    Ich hoffe ich kann verständlich machen was ich meine!

    Crypi
    Code:
    test=*# select * from stueckliste ;
     laufendenummer_stammdaten | laufendenummer_stueckliste
    ---------------------------+----------------------------
                             1 |                          1
                             2 |                          1
                             3 |                          1
    (3 rows)
    
    test=*# select * from preis1;
     laufendenummer_stammdaten |   datum    | preis | einheit
    ---------------------------+------------+-------+---------
                             1 | 2010-08-18 |   100 | Kilo
                             2 | 2010-08-16 |    10 | Kilo
    (2 rows)
    
    test=*# select * from preis2;
     laufendenummer_stammdaten |   datum    | preis | einheit
    ---------------------------+------------+-------+---------
                             3 | 2010-08-17 |   300 | Kilo
                             2 | 2010-08-19 |  1000 | Kilo
    (2 rows)
    
    test=*# select sl.laufendenummer_stammdaten, case when p1.datum > p2.datum then coalesce(p1.preis,0) else coalesce(p2.preis,0) end as preis, case when p1.datum > p2.datum then p1.einheit else p2.einheit end as einheit from stueckliste sl left join preis1 as p1 on (sl.laufendenummer_stammdaten=p1.laufendenummer_stammdaten) left join preis2 p2 on (sl.laufendenummer_stammdaten=p2.laufendenummer_stammdaten);
     laufendenummer_stammdaten | preis | einheit
    ---------------------------+-------+---------
                             1 |     0 |
                             2 |  1000 | Kilo
                             3 |   300 | Kilo
    (3 rows)
    besser?


    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

  6. #6
    akretschmer ist offline Super-Moderator
    Registriert seit
    29.10.2006
    Ort
    Nähe Dresden
    Beiträge
    5.337

    Standard

    Zitat Zitat von akretschmer Beitrag anzeigen
    Code:
    test=*# select * from stueckliste ;
     laufendenummer_stammdaten | laufendenummer_stueckliste
    ---------------------------+----------------------------
                             1 |                          1
                             2 |                          1
                             3 |                          1
    (3 rows)
    
    test=*# select * from preis1;
     laufendenummer_stammdaten |   datum    | preis | einheit
    ---------------------------+------------+-------+---------
                             1 | 2010-08-18 |   100 | Kilo
                             2 | 2010-08-16 |    10 | Kilo
    (2 rows)
    
    test=*# select * from preis2;
     laufendenummer_stammdaten |   datum    | preis | einheit
    ---------------------------+------------+-------+---------
                             3 | 2010-08-17 |   300 | Kilo
                             2 | 2010-08-19 |  1000 | Kilo
    (2 rows)
    
    test=*# select sl.laufendenummer_stammdaten, case when p1.datum > p2.datum then coalesce(p1.preis,0) else coalesce(p2.preis,0) end as preis, case when p1.datum > p2.datum then p1.einheit else p2.einheit end as einheit from stueckliste sl left join preis1 as p1 on (sl.laufendenummer_stammdaten=p1.laufendenummer_stammdaten) left join preis2 p2 on (sl.laufendenummer_stammdaten=p2.laufendenummer_stammdaten);
     laufendenummer_stammdaten | preis | einheit
    ---------------------------+-------+---------
                             1 |     0 |
                             2 |  1000 | Kilo
                             3 |   300 | Kilo
    (3 rows)
    besser?


    Andreas
    Okay, man sollte noch prüfen, ob es überhaupt Einträge in beiden Tabellen gibt. Muß man halt a bissl mit CASE basteln, das Prinzip sollte aber erkennbar sein, oder?

    Andreas
    --
    ads Das hatte dir akretschmer gestern schon gesagt und siehe da sobald du das machst, funktioniert es ;-)
    https://www.xing.com/profile/Andreas_Kretschmer7

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •  

Links: Tobias Bauer - IT- und Funkdienstleistungen   -   Bilderrahmen-kaufen.de - Der Onlineshop für Bilderrahmen & Fotorahmen   -   Funkforum