budda
Goto Top

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 face-smile

Gruß
Budda

Content-ID: 119516

Url: https://administrator.de/contentid/119516

Ausgedruckt am: 26.11.2024 um 14:11 Uhr

14695
14695 01.07.2009 um 15:45:18 Uhr
Goto Top
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
SlainteMhath
SlainteMhath 01.07.2009 um 15:54:00 Uhr
Goto Top
Hi,

Hm, auf die Gefahr hin jetzt total daneben zu liegen - is immerhin schon kurz vor Feierabend face-smile

Löst das hier nicht Dein Problem?
Select Kopf.*, Kunden.*
From Kopf
  Inner Join Zeile On Kopf.ID = Zeile.ID
  Inner Join Kunden On Kopf.ID = Kunden.KundenID

lg,
Slainte

EDIT: Tippfehler
Budda
Budda 01.07.2009 um 15:55:04 Uhr
Goto Top
Hallo Oli,

das Ziel ist es unseren Leuten im Verkauf eine Sicht für Excel zugeben übder die sie dann Ihre Kunden auswerten können.
Hierfür ist es leider erforderlich das alle Informationen zusammen sind.

Würde es performancemäßig was bringen mehrere Views zu machen und diese dann zum Schluss in einem View wieder zusammen zu fassen?

Ansonsten hab ich leider keine Idee wie wir das sonst lösen sollen.

Gruß
Budda
Budda
Budda 01.07.2009 um 16:07:40 Uhr
Goto Top
Hi,

ist das nicht so, wenn ich das mit den Join mache und die Spalte mit der ID leer ist das dann der komplette Datensatz nicht zurückgegeben wird?
Das Darf nicht sein. Es kann bei jeglichen Spalten mit ID's vorkommen das dort keine enthalten ist.

Gruß
Budda
SlainteMhath
SlainteMhath 01.07.2009 um 16:09:44 Uhr
Goto Top
Kommt auf den Join an face-smile

hier sind die verschiedenen Arten von JOINs gut erklärt: : http://aktuell.de.selfhtml.org/artikel/datenbanken/joins/
14695
14695 01.07.2009 um 16:14:14 Uhr
Goto Top
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
14695
14695 01.07.2009 um 16:17:13 Uhr
Goto Top
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
Budda
Budda 01.07.2009 um 16:23:44 Uhr
Goto Top
Hm ok, wenn ich mit nen Left join in die Kunden Tabelle gehe klappt das offensichtlich soweit.
Jetzt ist es aber so das ich 5 Spalten mit ID's habe die alle auf die Kunden Tabelle gehen.
Mache ich dann für jede Spalte einen eigenen Join?

Also so:

select Kopf.*, Kunden.*
From Kopf
Inner Join Zeile On Kopf.ID = Zeile.ID
Left Join Kunden On Kopf.ID = Kunden.KundenID
Left Join Kunden On Kopf.ID2 = Kunden.KundenID
Left Join Kunden On Kopf.ID3 = Kunden.KundenID

usw.
Biber
Biber 01.07.2009 um 17:21:47 Uhr
Goto Top
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:

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
Budda
Budda 02.07.2009 um 08:18:17 Uhr
Goto Top
Moin Biber,

danke schonmal für deinen ausführlichen Beitrag. Ich werde das gleich direkt mal antesten.

Habe allerdings noch eine Frage zu dieser Zeile:
"-" "Ku1.PLZ" & " " Ku1.Ort

Was genau bewirkt diese? Fasst sie die SPalten Zusammen zu einer?

Wir sprechen hier von einem SQL Server 2005. Ich hatte es gestern bereits ohne Aliase probiert, das ist mal voll in die Hose gegangen face-smile

Wir benutzen Views um die Daten in Excel Auswerten zu können.
Excel selber kann ja nur mit Views, Tabellen und Cubes arbeiten soweit ich weiss.
Tabellen ist in diesem Fall leider nich benutzbar, weil die User nicht über ausreichende Kenntnisse verfügen um sich dann Ihre Auswertungen zu erstellen.
Cubes haben wir hier keine eingerichtet und leider auch derzeit keine wirklichen Kenntnisse. Auch wenn es vermutlich die beste Variante wäre.

Gruß
Budda
Biber
Biber 02.07.2009 um 08:36:06 Uhr
Goto Top
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... face-wink

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

Die beiden fett angezeigten Felder füllt der View mit
select Z.zeilenInfo, K.ID , K.AufDatum,
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
Budda
Budda 02.07.2009 um 09:09:02 Uhr
Goto Top
Ah alles klar.
Wunderbar, dann versuch ich das gleich mal umzusetzen.

Das man es vielleicht nicht per Copy&Paste übernehmen kann macht nix. Will ja auch verstehen was ich da mache. Daher schon ganz gut das ich das selber nochmal umsetzen muß face-smile

Gruß
Budda