Cleverer mit JOIN?

  • VB.NET
  • .NET (FX) 3.0–3.5

Es gibt 12 Antworten in diesem Thema. Der letzte Beitrag () ist von ErfinderDesRades.

    Cleverer mit JOIN?

    Hiho,

    ich hab hier ein Query, was sicherlch schöner mit JOIN ginge, bei mir aber das ganze mit JOIN nicht in meine Hirnrinde Platz findet ;)

    SQL-Abfrage

    1. SELECT
    2. `3040_messdaten`.`tool`,
    3. `3040_messdaten`.`part`,
    4. `3040_messdaten`.`ol1`,
    5. `3040_messdaten`.`ow1`,
    6. `3040_messdaten`.`r12`,
    7. `3040_messdaten`.`r42`,
    8. `3040_rauheiten`.`lw`,
    9. `3040_rauheiten`.`cw`
    10. FROM
    11. 3040_messdaten , `3040_rauheiten`
    12. WHERE
    13. `3040_messdaten`.`tool` = '1' AND
    14. `3040_messdaten`.`part` = '242' AND
    15. `3040_rauheiten`.`tool` = '1' AND
    16. `3040_rauheiten`.`part` = '242';


    Wie würde ein Äquivalent mit JOIN dazu aussehen? :)
    Ok. Verbunden sind sie eigentlich nicht. (soweit ich das verstehe)
    Nur, das es in beiden Tabellen einmalige Kombinationen von 'tool' und 'part' gibt.

    Es gibt zwar hunderte Einträge von 'tool' 1, aber jeder Eintrag ist einmalig, wenn man ihn in Verbindung mit 'part' setzt.
    Als Primärschlüssel dient in beiden Tabellen ein ID-Feld, welches das Attribut AutoIncrement trägt.

    Das heisst aber nicht, dass ID 32 in Tabelle 3040_messwerte die gleiche tool/part-Kombination in Tabelle 3040_rauheiten beinhaltet.

    Die Beziehung zueinander ist folgende:

    3040_messwerte beinhaltet Messwerte, die ich an einem Bauteil mit einem Messschieber aufnehme.
    Für das gleiche Bauteil gibt es nochmals in 3040_rauheiten eine Zeile für die (mit einem Perthometer) ermittelten Rauheitswerte.
    Wenn du zwei Tabellen miteinander verknüpfen willst, dann muss das ja nach bestimmten Kriterien geschehen.
    Welche Einträge aus 3040_messdaten sollen mit welchen Einträgen aus 3040_rauheiten gejoint werden?
    Sind es etwa die tool/part Einträge, die in beiden Tabellen identisch sein müssen?

    Allgemein sieht ein Inner Join so aus:

    SQL-Abfrage

    1. SELECT *
    2. FROM tabelle1 INNER JOIN tabelle2 ON tabelle1.pk = tabelle2.pk
    Momenan sehen die Tabellen folgendermassen aus:

    Brainfuck-Quellcode

    1. 3040_rauheiten | 3040_messdaten
    2. +-------------+ +-------------+
    3. | COLUMN_NAME | | COLUMN_NAME |
    4. +-------------+ +-------------+
    5. | ID | | ID |
    6. | tool | | tool |
    7. | part | | part |
    8. | lw | | ol1 |
    9. | cw | | ol2 |
    10. | comment | | ow1 |
    11. | transfered | | ow2 |
    12. +-------------+ | r11 |
    13. | r12 |
    14. | r13 |
    15. | r21 |
    16. | r22 |
    17. | r23 |
    18. | r31 |
    19. | r32 |
    20. | r33 |
    21. | r41 |
    22. | r42 |
    23. | r43 |
    24. | comment |
    25. | transfered |
    26. +-------------+


    Wie zu sehen, sind nur die Felder ID, tool und part in beiden Tabellen vorhanden.
    ID ist eine vom DBMS verwaltete Spalte.

    So, wie ich das bisher verstanden habe, brauche ich noch ein weiteres Feld, welches eine Eindeutigkeit eines Bauteils bereitstellt.
    Also eine Kombination von tool und part.
    Beispielsweise ein Feld 'toolpart', welches für die Kombination von tool 1 und part 222 den Inhalt "1-222" trägt.

    Oder kann ich auch ein Vergleich mit zwei Feldern in einem JOIN-Query tätigen?

    SQL-Abfrage

    1. SELECT *
    2. FROM tabelle1 INNER JOIN tabelle2 ON tabelle1.foo = tabelle2.foo AND tabelle1.bar = tabelle2.bar
    Ja, das funktioniert so.

    Was mir noch auffällt:
    Wenn 3040_rauheiten sich nur auf Bauteile bezieht, die schon in den Messdaten 3040_messdaten drin stehen, dann besteht Redundanz und du solltest in 3040_rauheiten die Felder tool und part rausschmeißen und statdessen einen Fremdschlüssel auf 3040_messdaten einfügen.
    Natürlich kenne ich das Datenmodell nicht wirklich, der Rat ist zB. schon falsch, wenn es auch alleinstehende Rauheitsmessungen gibt ohne vorherige Messdaten.

    Counterbug schrieb:

    wenn es auch alleinstehende Rauheitsmessungen gibt ohne vorherige Messdaten


    Genau das ist der Fall.
    Es ist undefiniert, wann die Rauheiten oder die Messschieber-Daten erfasst werden, da dies an zwei unterschiedlichen Arbeitsplätzen aber nicht mit den gleichen Bauteilen passiert.

    Basierend auf deinem INNER JOIN Beispiel hab ich mal bisserl rumgespielt.

    SQL-Abfrage

    1. SELECT 3040_messdaten.*, 3040_rauheiten.lw, 3040_rauheiten.cw, 3040_rauheiten.comment AS raucomm, 3040_rauheiten.transfered AS rautrans
    2. FROM 3040_messdaten
    3. INNER JOIN 3040_rauheiten ON 3040_messdaten.tool = 3040_rauheiten.tool
    4. AND 3040_messdaten.part = 3040_rauheiten.part
    5. WHERE 3040_messdaten.tool =1
    6. AND 3040_messdaten.part =139


    Leider viel mir folgendes auf:

    Wenn ich ein Bauteil in der einen aber nicht der anderen habe, gibt mir der/die/das Query keine Zeile aus.
    Da es für mich aber genau darum geht, zu schauen, ob ein Bauteil schon in der einen oder anderen oder in beiden oder keinen steht, werde ich wohl um zwei seperate Querys nicht herum kommen.

    Aber ich glaube, genau dafür, wie sich JOIN verhält, ist es ja auch geschaffen.
    Also eher mein Fehler, da ich versuhe eine falsche Technik für mein Vorhaben einzusetzen :)

    hirnwunde schrieb:

    Genau das ist der Fall.
    Es ist undefiniert, wann die Rauheiten oder die Messschieber-Daten erfasst werden, da dies an zwei unterschiedlichen Arbeitsplätzen aber nicht mit den gleichen Bauteilen passiert.


    Man könnte die Bauteile als eigene Entitäten ansehen, sprich du legst eine Tabelle an, in der du für jedes Bauteil einen Datensatz anlegst.
    Und von deinen Messtabellen kannst du dann jeweils mit einem Fremdschlüssel auf das Bauteil referenzieren.
    -> keine Redundanz
    -> Messungen sind unabhängig voneinander, aber beziehen sich auf das selbe Bauteil.


    Der Inner Join gibt die nur die Schnittmenge beider Tabellen zurück, also die Einträge, bei denen die angegebenen Schlüssel der ON-Klausel identisch sind.


    Dann gibt es noch die Left/Right Outer Joins, die geben dir jeweils alle Einträge der linken/rechten Tabelle und zusätzlich die Schnittmenge beider Tabellen.

    Da es für mich aber genau darum geht, zu schauen, ob ein Bauteil schon in der einen oder anderen oder in beiden oder keinen steht, werde ich wohl um zwei seperate Querys nicht herum kommen

    Mit den Bauteilen als eigene Tabelle wäre das auch nur noch eine Abfrage.


    Ist das Datenmodell schon so vorgegeben und du kannst da nichts mehr dran ändern?
    Danke für die bisherigen Erklärungen!

    Nein, das DB-Modell (und die dazugehörigen Eingabemasken) ist (sind) von mir frei definierbar.
    In meiner ersten Version hatte ich es sogar in einer Tabelle.
    Allerdings wollte ich von den ganzen UPDATES weg.
    Denn, wenn an einem Platz schon das Bauteil gemessen wird, dann muss der andere Platz anstatt eines INSERT ein UPDATE absetzen.

    Mit den zwei Tabellen wollte ich mir aber die UPDATES sparen und der Einfachheit haber nur INSERTs nutzen.
    Scheinbar war mein erster Ansatz, jedes Bauteil hat in einer Tabelle alle Daten besser, als der Versuch es in zwei Tabellen auszulagern. Zumal ja in den zwei Tabellen unnötigerweise drei Spalten doppelt vorhanden sind (ID, tool & part)
    Diese fallen ja weg, wenn es in einer Tabelle steht.

    Aber da es sich hier nur über ca. 10.000-15.000 Datensätze handelt, hielt ich das nicht für so gewichtig.

    Ja. Vielleicht fahre ich weiter mit der einen Tabelle in dem alles drin steht und ich wenn nötig UPDATEs fahre.

    Andereseits ist ja Left/Right Outer Joins genau das, was ich benötige.
    ok ... das wäre natürlich auch eine Variante.

    Tabelle Bauteil müsste dann aber ebenso einen eindeutigen Bauteil (FK) beinhalten, oder? sodass alle drei Tabellen eine schnittmenge hätten.
    Oder sehe ich das falsch?

    Und in Tabelle Bauteil könnte dann auch noch jeweils ein Feld (bool) für rauheit und messung hinein, sodass ich die Komplettheit (komsiches Wort!) eines Bauteils in einer Tabelle erfassen kann und eben nciht über mehrere Tabellen muss.

    Wofür steht eig. die Abkürzung (FK)? ;)
    In der Tabelle Bauteil wird für jedes Bauteil ein Datensatz angelegt und die Id wird durchnummeriert und ist eindeutig.
    Die Information, ob ein Bauteil Messungen hat, besteht bereits durch die Datenstruktur, dadurch brauchst du kein extra Feld mit unnötigen Daten.

    Bsp. hat das Bauteil mit Id 37 schon Messungen? Mache eine Query über die Messungstabelle mit dem Zusatz WHERE Bauteil = 37. Da kommen entweder Ergebnisse heraus oder eben nicht.

    FK steht für Foreign Key, Fremdschlüssel. Das ist eine Spalte, die auf den Primärschlüssel einer anderen Tabelle referenziert.
    Primärschlüssel (PK) ist ein eindeutig, indentifizierender Wert, für den verwendet man gerne die Id, weil die indizierte Suche nach einer Zahl bei riesen Datenmengen am schnellsten funktioniert.

    Du solltest dich unter Umständen mal mit dem relationalen Datenbankmodell beschäftigen.