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-Key: 119516

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

Printed on: April 19, 2024 at 12:04 o'clock

Mitglied: 14695
14695 Jul 01, 2009 at 13:45:18 (UTC)
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
Member: SlainteMhath
SlainteMhath Jul 01, 2009 at 13:54:00 (UTC)
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
Member: Budda
Budda Jul 01, 2009 at 13:55:04 (UTC)
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
Member: Budda
Budda Jul 01, 2009 at 14:07:40 (UTC)
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
Member: SlainteMhath
SlainteMhath Jul 01, 2009 at 14:09:44 (UTC)
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/
Mitglied: 14695
14695 Jul 01, 2009 at 14:14:14 (UTC)
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
Mitglied: 14695
14695 Jul 01, 2009 at 14:17:13 (UTC)
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
Member: Budda
Budda Jul 01, 2009 at 14:23:44 (UTC)
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.
Member: Biber
Biber Jul 01, 2009 at 15:21:47 (UTC)
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
Member: Budda
Budda Jul 02, 2009 at 06:18:17 (UTC)
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
Member: Biber
Biber Jul 02, 2009 at 06:36:06 (UTC)
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
Member: Budda
Budda Jul 02, 2009 at 07:09:02 (UTC)
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