Entwickler-Ecke

Datenbanken - SQL Abfrage Berechnungsproblem


bis11 - Do 05.12.02 17:46
Titel: SQL Abfrage Berechnungsproblem
Hallo Leute,

irgendwie schaffe ich das nicht, ich habe eine Abfrage, die mir aus zwei Tabellen jeweils die Summe bestimmter Artikel raussucht. Die Abfrage ist folgendermaßen :


Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
  bestand := TStringList.Create;                                   
  for i:=0 to HerstellerZub.Count-1 do begin                  
    with DatenModul.ADOQueryZubehoer do begin                                   
      SQL.Clear;                                                   
      SQL.Add(PChar(selectwhereorderspalte(PChar('ZubehoerTyp'),        
         PChar('Zubehoerstammdaten'),PChar('ZubehoerHersteller'),               
         PChar(HerstellerZub.Strings[i]),PChar('ZubehoerTyp'))));               
      Open;                                                                     
      forherstellerzub := HerstellerZub.Strings[i];               
      Active := True;                                                        
      while not Eof do begin                                               
        summe1 := PChar(selectsumwhere('ZubehoerEingang','ZubehoerMenge',       
           'ZubehoerHersteller','ZubehoerTyp',PChar(HerstellerZub.Strings[i]), 
           PChar(Fields[0].AsString)));     
        summe2 := PChar(selectsumwhere('ZubehoerAusgang','ZubehoerMenge',       
           'ZubehoerHersteller','ZubehoerTyp',PChar(HerstellerZub.Strings[i]),  
           PChar(Fields[0].AsString)));       
        bestand.Add('SELECT ZubehoerHersteller+' + QuotedStr(' ') +             
             '+ZubehoerTyp AS Komponenten,(' + summe1 + ') - (' + summe2 +      
             ') AS Bestand FROM ZubehoerEingang WHERE ZubehoerHersteller=' +
             QuotedStr(forherstellerzub) + ' AND ZubehoerTyp=' +                
             QuotedStr(Fields[0].AsString));                                    
        next;                                                                   
      end;                                                                      
      Active := False;                                                         
    end;                                                                        
  end;                                                                          
  with DatenModul.ADOQueryAbfrageEingang do begin                              
    SQL.Clear;                                            
    for j:=0 to bestand.Count-1 do begin       
      SQL.Add(bestand.Strings[j]);                
      if j = bestand.Count-1 then SQL.Add('') 
      else SQL.Add('UNION')   
    end;   
    Open; 
  end;                                 
  AbfrageErgebnis := TAbfrageErgebnis.Create(Application);                      
  AbfrageErgebnis.Show;


Er macht mir ja auch alles, nur wenn bei einem Produkt noch kein Ausgang gebucht wurde, habe ich in der Übersicht zum Schluß bei Bestand nichts drin stehen. Ich vermute, daß das daher kommt weil er in der Tabelle ZubehoerAusgang nichts findet und so die Berechnung nicht durchführen kann. Wie kann ich diese Sache jetzt abfangen und das er bei der Suche, wenn er nichts findet einfach die Zahl 0 in den Berechnungsskript einsetzt ?


LCS - Do 05.12.02 17:58

Hi
das Problem liegt an der Art der Tabellenverknüpfung. Du verwendest einen einfachen Straight-Join, der dir in der Tat nur dann ein Ergebnis liefert, wenn die Verbundenen Felder in allen Tabellen den gleichen Wert haben.
Du solltest deine SQL Anweisung in etwa so gestalten:

Quelltext
1:
2:
3:
4:
SELECT felder from Tabelle1
LEFT JOIN Tabelle2 on (Tabelle1.Feld = Tabelle2.Feld)
LEFT JOIN Tabelle3 on (Tabelle1.Feld = Tabelle3.Feld)
usw.

Aus diese Weise bekommst du alle Datensätze der Tabelle1, auch wenn in Tabelle2 oder Tabelle3 keine Datensätze dazu vorhanden sind. Die entsprechenden Felder sind dann NULL. Das allerdings schaft dir wieder Probleme wenn du versuchst diese Werte mit der SUM-Funktion zu summieren. Einige Datenbanken betrachten dann den NULL-Wert als 0 und liefern trotzdem ein korrektes Ergebnis, andere (z.B. Interbase) leider nicht.

Gruss Lothar


bis11 - Do 05.12.02 18:41

Ich habe doch keine direkte Tabellenverknüpfung. Ich lese nur den Gesamtwert aus der Eingangstabelle und den Gesamtwert aus der Ausgangstabelle und sage dann Eingangstabelle - Ausgangstabelle. Diesen errechneten Wert, trage ich dann per Select-Befehl in ein neues Feld namens "Bestand" ein. Dieses Funktioniert ja auch hervorragend, solange es für den Artikel x-Eingänge gibt und x-Ausgänge gibt. Es klappt nur nicht, wenn es Eingänge gibt und keine Ausgänge gibt. Deshalb verstehe ich nicht ganz, was ich jetzt da mit dem SQL-Skript anfangen soll. Ich steige durch Deine Beschreibung nicht durch.


hansa - Do 05.12.02 20:12

Hi bis11,

was Lothar mit den NULL-Werten sagt, das mußt Du beachten. Damit gibts eventuell Performance - Probleme oder sonstwas. Lese Dir das hier mal durch: http://www.dibug.de/download/oop_ek2000.zip

Ist von Holger Klemt. Habe es nur überflogen, aber da steht im Zusammenhang mit NULL - Werten interessantes drin.

Gruß
Hansa


bis11 - Do 05.12.02 23:02

Hi,

also ich danke euch erstmal für eure Antworten, nur leider löst das nicht das eigentliche Problem. Denn wenn ich nur die Abfrage nach dem Schema vom Lothar mache, bekomme ich keine Summe aus der Eingangstabelle und aus der Ausgangstabelle zusammen. Könnt Ihr mir da weiterhelfen ?


LCS - Fr 06.12.02 09:14

Hi
dann hab ich das Ganze bis jetzt falsch interpretiert :roll: Ich werd noch mal drüber grübeln.

Gruss Lothar


bis11 - Fr 06.12.02 16:37

Es ist doch ganz einfach, Du hast eine Eingangstabelle. In diese Tabelle schreibst Du den Wareneingang rein, wieviel von jeder Ware gekommen ist. Hast Du jetzt neue Ware drin, die Du vorher noch nicht hattest, hast Du somit auch keinen Eintrag in der Ausgangstabelle. Nimmst Du dann meine Abfrage von meinem 1. Posting, bekommst Du für die neue Ware in der Spalte Bestand nichts angezeigt. Das ist das ganze Problem, Du bekommst erst eine Anzeige, wenn Du für die neu eingegangene Ware auch einen Ausgang verbucht hast in der Ausgangstabelle. Und das möchte ich vermeiden.


bis11 - So 08.12.02 12:36

Hi,

ich habe das ganze jetzt anderst gelöst. Ich habe eine Funktion geschrieben, die mir die Anzahl der Einträge in der Ausgangstabelle ausliest. Kommt beim auslesen kein Wert zurück, so gibt mir die Funktion 0 zurück. Und dann habe ich nur noch eine IF-Schleife eingebaut, die diesen Wert abfragt und dann passend in die Variable "summe2" einsetzt.

Trotzdem danke für eure Hilfe.