SQL per Unterabfrage mehrer Spalten holen
Hallo,
das Problem ist etwas schwer zu beschreiben. Ich habe eine vorgegebene Datenbank mit mehreren Tabellen die Informationen zu Belegen enthalten.
Nun möchten wir ein View was uns alle möglichen Daten bereitstellt um diese auswerten zu können.
Es gibt eine Tabelle Kopf und eine Zeile. Diese beiden haben wir über deren ID mit einem innerjoin verbunden. Soweit so gut. Nun kommt das Problem.
Es gibt in diesen beiden Tabellen nun diverse Spalten mit ID's für Datensätze in anderen Tabellen. Zum Beispiel eine KundenID. Anhand dieser ID kann man dann in der Kunden Tabelle den Kunden nachschlagen.
Diese ID möchten wir in unserer Abfrage durch Firmenname, Strasse, PLZ und Ort ersetzen.
Dieses Prinzip gibt es dann noch ein paar mal mit anderen ID's auf andere Tabellen. Aber immer das selbe Prinzip.
Nun haben wir das bisher so gelöst:
Select *,
(Select Firmenname from Kunden where ID = Kopf.KundenID) AS Firmenname,
(Select Strasse from Kunden where ID = Kopf.KundenID) AS Strasse
From Kopf Inner Join Zeile On Kopf.ID = Zeile.ID
Das ganze haben wir dann für jede Spalte realisiert die wir Anhand der ID noch benötigen. Sprich die Abfrage ist mittlerweile verdammt groß und kann jetzt nicht mehr gespeichert werden, da die maximalen Tabellennamen die in einem View verwendet werden dürfen erreicht ist. Zudem ist die Abfrage natürlich auch nicht gerade performance Optimiert.
Vielleicht hat ja jemand einen Tipp für mich wie man das besser und Performanceorientierter lösen kann. Da ich mal davon ausgehe das unsere Lösung nicht gerade das gelbe vom Ei ist
Gruß
Budda
das Problem ist etwas schwer zu beschreiben. Ich habe eine vorgegebene Datenbank mit mehreren Tabellen die Informationen zu Belegen enthalten.
Nun möchten wir ein View was uns alle möglichen Daten bereitstellt um diese auswerten zu können.
Es gibt eine Tabelle Kopf und eine Zeile. Diese beiden haben wir über deren ID mit einem innerjoin verbunden. Soweit so gut. Nun kommt das Problem.
Es gibt in diesen beiden Tabellen nun diverse Spalten mit ID's für Datensätze in anderen Tabellen. Zum Beispiel eine KundenID. Anhand dieser ID kann man dann in der Kunden Tabelle den Kunden nachschlagen.
Diese ID möchten wir in unserer Abfrage durch Firmenname, Strasse, PLZ und Ort ersetzen.
Dieses Prinzip gibt es dann noch ein paar mal mit anderen ID's auf andere Tabellen. Aber immer das selbe Prinzip.
Nun haben wir das bisher so gelöst:
Select *,
(Select Firmenname from Kunden where ID = Kopf.KundenID) AS Firmenname,
(Select Strasse from Kunden where ID = Kopf.KundenID) AS Strasse
From Kopf Inner Join Zeile On Kopf.ID = Zeile.ID
Das ganze haben wir dann für jede Spalte realisiert die wir Anhand der ID noch benötigen. Sprich die Abfrage ist mittlerweile verdammt groß und kann jetzt nicht mehr gespeichert werden, da die maximalen Tabellennamen die in einem View verwendet werden dürfen erreicht ist. Zudem ist die Abfrage natürlich auch nicht gerade performance Optimiert.
Vielleicht hat ja jemand einen Tipp für mich wie man das besser und Performanceorientierter lösen kann. Da ich mal davon ausgehe das unsere Lösung nicht gerade das gelbe vom Ei ist
Gruß
Budda
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 119516
Url: https://administrator.de/contentid/119516
Ausgedruckt am: 26.11.2024 um 14:11 Uhr
12 Kommentare
Neuester Kommentar
Hi,
was ist denn das Ziel? Eine Tabelle (/Sicht) mit 5000 Spalten?
Ich würde darüber nachdenken, ob ihr nicht mit mehreren Sichten (auch übersichtlicher) klar kommt. Dass die maximale Anzahl verwendbarer Tabellen erreicht ist, spricht eindeutig GEGEN euer "Design".
Grüße
OLI
was ist denn das Ziel? Eine Tabelle (/Sicht) mit 5000 Spalten?
Ich würde darüber nachdenken, ob ihr nicht mit mehreren Sichten (auch übersichtlicher) klar kommt. Dass die maximale Anzahl verwendbarer Tabellen erreicht ist, spricht eindeutig GEGEN euer "Design".
Grüße
OLI
Kommt auf den Join an
hier sind die verschiedenen Arten von JOINs gut erklärt: : http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/
hier sind die verschiedenen Arten von JOINs gut erklärt: : http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/
Hi Budda,
so etwas in der Art (einzelne Views zusammenfassen) dachte ich. Ob du damit auch die Performance positiv beeinflussten kannst, keine Ahnung bei großen Datenbeständen -> ausprobieren.
Darüber hinaus: wenn z.B. die Kundenadressen nicht unbedingt in seperaten Spalten vorliegen müssen könntest du auch darüber nachdenken die Spalten zusammen zu fassen (SELECT LastName + ', ' + Firstname AS Name FROM Customers)... Das macht es ggf. übersichtlicher.
Grüße
Oli
so etwas in der Art (einzelne Views zusammenfassen) dachte ich. Ob du damit auch die Performance positiv beeinflussten kannst, keine Ahnung bei großen Datenbeständen -> ausprobieren.
Darüber hinaus: wenn z.B. die Kundenadressen nicht unbedingt in seperaten Spalten vorliegen müssen könntest du auch darüber nachdenken die Spalten zusammen zu fassen (SELECT LastName + ', ' + Firstname AS Name FROM Customers)... Das macht es ggf. übersichtlicher.
Grüße
Oli
Kann vorkommen, ist so. Unter SQL Server teste ich mit ISNULL(ID, '') ob ein Wert vorhanden ist oder die Spalte NULL ist. Wenn eine ID eingetragen ist wird die ID, sonst einfach ein leerer String zurück gegeben.
Grüße
OLI
Grüße
OLI
Moin Budda,
in Prinzip jein.
Richtig ist: Du brauchst für jeden LEFT JOIN (auch wenn er immer wieder auf die KUNDEN-Tabelle geht, jeweis eine eigene JOIN-"Zeile" bei der View-Deklaration.
Falsch ist: in jedm LEFT JOIN muss die KUNDEN-Tablle auch unter einem anderen ALIAS angesprochen werden.
Sonst dreht Deine "vorgegebene Datenbank" (hat die auch einen Spitznamen? Sowas wie mySQL oder Oracle oder TeraData?) am Rad.
Noch falscher ist: einen VIEW, eine "Sicht" anzulegen, um alle KOPF-Felder und alle KUNDEN-Felder blind anzuzeigen, so wie deren physischen Namen nun mal sein mögen und unabhängig davon, ob es interne, externe, technische oder informationstransportierende sind.
Hast Du Dich mal versucht, mit dem Thema VIEWs auseinanderzusetzen und wenn ja, was ist dazwischengekommen?
Beispielskizze, soweit sich etwas OHNE Kenntnis des DB-Blechs und ohne Kenntnis des Datenmodells/der Relationen erraten lässt:
Bitte mehr Details...
Grüße
Biber
in Prinzip jein.
Richtig ist: Du brauchst für jeden LEFT JOIN (auch wenn er immer wieder auf die KUNDEN-Tabelle geht, jeweis eine eigene JOIN-"Zeile" bei der View-Deklaration.
Falsch ist: in jedm LEFT JOIN muss die KUNDEN-Tablle auch unter einem anderen ALIAS angesprochen werden.
Sonst dreht Deine "vorgegebene Datenbank" (hat die auch einen Spitznamen? Sowas wie mySQL oder Oracle oder TeraData?) am Rad.
Noch falscher ist: einen VIEW, eine "Sicht" anzulegen, um alle KOPF-Felder und alle KUNDEN-Felder blind anzuzeigen, so wie deren physischen Namen nun mal sein mögen und unabhängig davon, ob es interne, externe, technische oder informationstransportierende sind.
Hast Du Dich mal versucht, mit dem Thema VIEWs auseinanderzusetzen und wenn ja, was ist dazwischengekommen?
Beispielskizze, soweit sich etwas OHNE Kenntnis des DB-Blechs und ohne Kenntnis des Datenmodells/der Relationen erraten lässt:
CREATE View ExcelExport (ZeilenInfo, Auftrag, AuftrDatum, Kunde, KundenAddr,
Lieferant, LieferantenAdr, Lieferdatum, RechDatum, RechEingang) as
select Z.zeilenInfo, K.ID , K.AufDatum,
Ku1.Name ,
Ku1.Land || "-" || Ku1.PLZ || " "|| Ku1.Ort || ", " || Ku1.Str ,
Ku2.Name ,
Ku2.Land || "-" || Ku2.PLZ || " " || Ku2.Ort || ", "|| Ku2.Str ,
K.LiefDatum,
K.RechDatum,
K.RechEingang
FROM Kopf K Inner Join Zeile Z On K.ID = Z.ID
Left Join Kunden k1 On K.ID = K1.KundenID
Left Join Kunden K2 On K.ID2 = K2.KundenID
Order by kopf.id, zeile.pos.....
Bitte mehr Details...
Grüße
Biber
Moin Budda,
wie gestern geschrieben... ist nur eine grobe (und natürlich ungetestete) Skizze.
Ich habe eben gerade bei der Zeile, die Du zitiert hast, auch gleich irgendwelche Tippfehler bemerkt und (hoffentlich) oben im Code berichtigt.
---> Kann natürlich trotzdem sein, dass diese Skizze nicht nach einfachem Copy&Paste produktiv gesetzt werden kann...
zu Deiner Frage:
Ja, ich habe in dem View ja unter anderem als nach außen/nach Excel sichtbare Felder definiert:
Die beiden fett angezeigten Felder füllt der View mit
.. oder auf deutscher: "KundenAddr" wird gefüllt mit Feld "Land" plus "-" plus "PLZ" plus Leerzeichen plus "Ort"...
---> also Ergebnis ungefähr "D-12345 Whereever, Sackgasse 7" wird in View-Spalte "KundenAddr" angezeigt.
!! Bitte nicht buchstabengetreu übernehmen, sondern nur sinngemäß. !! (Ist schnell hingepfuscht worden gestern)
Grüße
Biber
wie gestern geschrieben... ist nur eine grobe (und natürlich ungetestete) Skizze.
Ich habe eben gerade bei der Zeile, die Du zitiert hast, auch gleich irgendwelche Tippfehler bemerkt und (hoffentlich) oben im Code berichtigt.
---> Kann natürlich trotzdem sein, dass diese Skizze nicht nach einfachem Copy&Paste produktiv gesetzt werden kann...
zu Deiner Frage:
Habe allerdings noch eine Frage zu dieser Zeile:
"-" | "Ku1.PLZ" & " " Ku1.Ort |
Ja, ich habe in dem View ja unter anderem als nach außen/nach Excel sichtbare Felder definiert:
CREATE View ExcelExport (ZeilenInfo, Auftrag, AuftrDatum, Kunde, KundenAddr,
Lieferant, LieferantenAdr,
Lieferdatum, RechDatum, RechEingang) as ...
Lieferant, LieferantenAdr,
Lieferdatum, RechDatum, RechEingang) as ...
Die beiden fett angezeigten Felder füllt der View mit
select Z.zeilenInfo, K.ID , K.AufDatum,
Ku1.Name ,
Ku1.Name ,
"-" | Ku1.PLZ | " " | Ku1.Ort | ", " |
.. oder auf deutscher: "KundenAddr" wird gefüllt mit Feld "Land" plus "-" plus "PLZ" plus Leerzeichen plus "Ort"...
---> also Ergebnis ungefähr "D-12345 Whereever, Sackgasse 7" wird in View-Spalte "KundenAddr" angezeigt.
!! Bitte nicht buchstabengetreu übernehmen, sondern nur sinngemäß. !! (Ist schnell hingepfuscht worden gestern)
Grüße
Biber