SQL-Suche über mehrere Tabellen-Relationen hinweg

  • VB.NET

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von Bit-Bieger.

    SQL-Suche über mehrere Tabellen-Relationen hinweg

    Hallo Forum!

    Zuerst möchte ich mich bei allen für die tollen Beiträge und Tutorials hier herzlich bedanken. :thumbsup:
    Eine sehr wertvolle Unterstützung für einen SQL-Anfänger zum Einstieg in die Datenbänkerei!

    Doch einen Punkt hab ich beim besten Willen nicht kapiert, vielleicht könnt Ihr mir auf die Sprünge helfen:

    Wie kann ich über mehrere Tabellen-Relationen hinweg eines typisierten Datasets hinweg Datensätze suchen, die in Relation zueinander stehen?

    Beispiel Lagerverwaltung:

    [siehe Bild mit Tabellen im Anhang - hab es hier nicht einfügen können ?( ]


    Nun möchte ich eine Abfrage schreiben, die mit dem
    Input: id_halle & id_besitzer den
    Output: Anzahl aller Schrauben vom Besizter-x in gesamter Halle-x
    liefert (und die möglichst elegant programmiert ist und wenig Laufzeit benötigt.)

    Bislag habe ich nur 2 Ansätze gefunden die sich aber nicht so toll anfühlen:

    1. mit Expression-Columns
    (diese "bähen" das Datenmodell aber immer weiter auf, sind in der Anzahl beschränkt & Laufzeit ist mir unklar)

    2. mit ineinander geschachtelten Schleifen die Tabellen anhand der Relationen zu durchlaufen
    ( = Holzhammer-Methode? :D Laufzeit-kritisch und nicht gerade elegant)

    Gibt es für einen solch 'simplen' Anwendungsfall wirklich nix einfaches oder hab ich nur Tomaten auf den Augen 8| ?

    Würde mich über einen Wegweiser zum 'Königsweg' sehr freuen 8-)
    Bilder
    • Tabellen.jpg

      49,19 kB, 955×210, 56 mal angesehen
    zunächstmal täte ich empfehlen, im Datenmodell die überflüssigen tbl_-Prefixe zu entfernen.
    Dann kann man mit linq recht leicht abfragen:

    VB.NET-Quellcode

    1. dim halle As HalleRow, besitzer as BesitzerRow
    2. dim alleKistenPerBesitzerHalle = besitzer.GetKisteRows.Where(function(k)k.PaletteRow.ContainerRow.HalleRow is halle)' testweise für Debug-Zwecke ein .ToArray() anhängen.
    3. dim anzahlSchrauben = alleKistenPerBesitzerHalle.Sum(function(k)k.AnzahlSchrauben)
    Das wäre imo der Königsweg.
    GeschwindigkeitsOptimierungen sind möglich, aber glaub nicht erforderlich.
    (Wenn du das umschreibst auf deine Tbl_-Dinger, poste mal den Code - zum Vergleich der Leserlichkeit an diesem Punkt.)
    Das mit dem .ToArray() ist gut zum Debuggen, es verwandelt die - schlecht zu debuggende - query alleKistenPerBesitzerHalle in ein normales Kisten-Array, dessen Inhalt man am Haltepunkt im Lokal-Fenster bequem einsehen kann.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „ErfinderDesRades“ ()

    Hallo ErfinderDesRades,

    vielen tausend DANK für die superschnelle Antwort!!! :thumbsup:

    genau das war es, was ich gebraucht und vergeblich gesucht habe...es funktioniert 1A!!! :thumbup:

    (... und die TBL_'s habe ich gleich entfert - besser so.)

    Anbei der 'schnelle' TestCode mit Debug-Ausgabe.
    Erst werden die Tabellen mit Datensätzen gefüllt, dann 2 Abfragen für die erste Halle für Besitzer1 und dann für Besitzer2, schließlich die Ausgabe der Summe und des Inhaltes des gesamten Suchergebnisses

    Mit 'N' kann die Anzahl der Hallen, deren Container, deren Paletten, deren Kisten (*2) eingestellt werden.

    Kisten vom ersten Benutzer enthaltenten jeweils 5 Schrauben
    Kisten vom zweiten Benutzer enthaltenten jeweils 10 Schrauben

    nochmals vielen Dank für Deine Unterstützung!!!

    VB.NET-Quellcode

    1. Option Explicit On
    2. Option Strict On
    3. Public Class Form1
    4. Private Sub Button1_Click_1(sender As Object, e As EventArgs) Handles Button1.Click
    5. DataSet11.Clear()
    6. Const n = 2
    7. Dim idHalle As Integer = 0
    8. Dim idContainer As Integer = 0
    9. Dim idPalette As Integer = 0
    10. Dim idKiste As Integer = 0
    11. For idBesitzer = 0 To n - 1
    12. DataSet11.Besitzer.AddBesitzerRow(idBesitzer)
    13. Next
    14. For iHalle = 0 To n - 1
    15. DataSet11.Halle.AddHalleRow(idHalle)
    16. For iContainer = 0 To n - 1
    17. DataSet11.Container.AddContainerRow(idContainer, DataSet11.Halle(idHalle))
    18. For iPalette = 0 To n - 1
    19. DataSet11.Palette.AddPaletteRow(idPalette, DataSet11.Container(idContainer))
    20. For iKiste = 0 To n - 1
    21. DataSet11.Kiste.AddKisteRow(idKiste, DataSet11.Palette(idPalette), DataSet11.Besitzer(0), 5)
    22. idKiste += 1
    23. Next
    24. For iKiste = 0 To n - 1
    25. DataSet11.Kiste.AddKisteRow(idKiste, DataSet11.Palette(idPalette), DataSet11.Besitzer(1), 10)
    26. idKiste += 1
    27. Next
    28. idPalette += 1
    29. Next
    30. idContainer += 1
    31. Next
    32. idHalle += 1
    33. Next
    34. Dim halle As DataSet1.HalleRow, besitzer As DataSet1.BesitzerRow
    35. Dim alleKistenPerBesitzerHalle As DataSet1.KisteRow()
    36. Dim anzahlSchrauben As Integer
    37. halle = DataSet11.Halle(0)
    38. besitzer = DataSet11.Besitzer(0)
    39. alleKistenPerBesitzerHalle = besitzer.GetKisteRows.Where(Function(k) k.PaletteRow.ContainerRow.HalleRow Is halle).ToArray
    40. anzahlSchrauben = alleKistenPerBesitzerHalle.Sum(Function(k) k.anzahl_schrauben)
    41. Console.WriteLine("Anzahl Schrauben: " & anzahlSchrauben)
    42. For i = 0 To alleKistenPerBesitzerHalle.Count - 1
    43. Console.WriteLine("idPalette: " & alleKistenPerBesitzerHalle(i).refid_palette.ToString & " | " &
    44. "idKiste: " & alleKistenPerBesitzerHalle(i).id_kiste.ToString & " | " &
    45. "IdBesitzer: " & alleKistenPerBesitzerHalle(i).refid_besitzer.ToString & " | " &
    46. "Anz. Schrauben: " & alleKistenPerBesitzerHalle(i).anzahl_schrauben & " | ")
    47. Next
    48. Console.WriteLine("")
    49. halle = DataSet11.Halle(0)
    50. besitzer = DataSet11.Besitzer(1)
    51. alleKistenPerBesitzerHalle = besitzer.GetKisteRows.Where(Function(k) k.PaletteRow.ContainerRow.HalleRow Is halle).ToArray
    52. anzahlSchrauben = alleKistenPerBesitzerHalle.Sum(Function(k) k.anzahl_schrauben)
    53. Console.WriteLine("Anzahl Schrauben: " & anzahlSchrauben)
    54. For i = 0 To alleKistenPerBesitzerHalle.Count - 1
    55. Console.WriteLine("idPalette: " & alleKistenPerBesitzerHalle(i).refid_palette.ToString & " | " &
    56. "idKiste: " & alleKistenPerBesitzerHalle(i).id_kiste.ToString & " | " &
    57. "IdBesitzer: " & alleKistenPerBesitzerHalle(i).refid_besitzer.ToString & " | " &
    58. "Anz. Schrauben: " & alleKistenPerBesitzerHalle(i).anzahl_schrauben & " | ")
    59. Next
    60. 'Output:
    61. 'Anzahl Schrauben: 40
    62. 'idPalette: 0 | idKiste: 0 | IdBesitzer: 0 | Anz. Schrauben: 5 |
    63. 'idPalette: 0 | idKiste: 1 | IdBesitzer: 0 | Anz. Schrauben: 5 |
    64. 'idPalette: 1 | idKiste: 4 | IdBesitzer: 0 | Anz. Schrauben: 5 |
    65. 'idPalette: 1 | idKiste: 5 | IdBesitzer: 0 | Anz. Schrauben: 5 |
    66. 'idPalette: 2 | idKiste: 8 | IdBesitzer: 0 | Anz. Schrauben: 5 |
    67. 'idPalette: 2 | idKiste: 9 | IdBesitzer: 0 | Anz. Schrauben: 5 |
    68. 'idPalette: 3 | idKiste: 12 | IdBesitzer: 0 | Anz. Schrauben: 5 |
    69. 'idPalette: 3 | idKiste: 13 | IdBesitzer: 0 | Anz. Schrauben: 5 |
    70. 'Anzahl Schrauben: 80
    71. 'idPalette: 0 | idKiste: 2 | IdBesitzer: 1 | Anz. Schrauben: 10 |
    72. 'idPalette: 0 | idKiste: 3 | IdBesitzer: 1 | Anz. Schrauben: 10 |
    73. 'idPalette: 1 | idKiste: 6 | IdBesitzer: 1 | Anz. Schrauben: 10 |
    74. 'idPalette: 1 | idKiste: 7 | IdBesitzer: 1 | Anz. Schrauben: 10 |
    75. 'idPalette: 2 | idKiste: 10 | IdBesitzer: 1 | Anz. Schrauben: 10 |
    76. 'idPalette: 2 | idKiste: 11 | IdBesitzer: 1 | Anz. Schrauben: 10 |
    77. 'idPalette: 3 | idKiste: 14 | IdBesitzer: 1 | Anz. Schrauben: 10 |
    78. 'idPalette: 3 | idKiste: 15 | IdBesitzer: 1 | Anz. Schrauben: 10 |
    79. End Sub
    80. End Class