Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   knifflige KriterienAbfrage einer Datenbank! (https://www.delphipraxis.net/132572-knifflige-kriterienabfrage-einer-datenbank.html)

daNiii 15. Apr 2009 10:17

Datenbank: Access • Version: 2007 • Zugriff über: SQL... siehe unten

knifflige KriterienAbfrage einer Datenbank!
 
HI!!!
hier mal eine sehr knifflige aufgabenstellung!
ich weis auch gar nicht ob es für mein Problem überhaupt eine Lösung gibt.
Hierbei handelt es sich um ein Programm, welches einen zeigt für welche Seminare man angemeldet ist und welche Seminare man nicht besucht.
Die Struktur der DAtenbank findest du im Anhang.

Ausgangssituation: ich habe bereits ein Listview erstellt, in dem alle Seminare angezeigt werden bei denen Der User angemeldet wird.

Problem: ich habe ein zweites Listview, in dem sollte alle übrigen Seminare (bei denen der User nicht angemeldet ist)angezeigt werden.

Hier mein Programmieransatz:

Delphi-Quellcode:
 
//erstes Listview: funktioniert problemlos
       adoquery1.close;
      adoquery1.SQL.Clear;
      adoquery1.SQL.Add('SELECT Anmeldungen.SID, Seminare.Seminartitel, Seminare.Datum, Anmeldungen.AID, Anmeldungen.MID FROM Seminare INNER JOIN Anmeldungen ON Seminare.[SID] = Anmeldungen.[SID] WHERE (((Anmeldungen.MID)=' +inttostr(Mitarbeiter)+')) ORDER BY Seminare.SID');
      adoquery1.open;
      while not adoquery1.eof do begin
        LI := Listview1.items.Add;
        LI.Caption := inttostr(adoquery1.FieldValues['SID']);
        LI.subitems.add(adoquery1.FieldValues['Seminartitel']);
        LI.subitems.add(datetostr(adoquery1.FieldValues['Datum']));
        LI.subitems.add(inttostr(adoquery1.FieldValues['AID']));
        SIDcounter:= SIDcounter +1;
       adoquery1.next;
       end;
       adoquery1.close;

//zweites Listview:
//Der SIDcounter zählt die zeilen im ersten Listview und somit die Anzahl der angemeldeten Seminare
//SID_angemeldet (array Variable) speichert welche Seminare im Listview1 eingetragen sind.
 for I := 1 to SIDcounter do begin
                  SID_angemeldet[I] := strtoint(LI.caption[I]);
                   end;
//SQLCODE(array VAriable): Teile des späteren SQLcodes.
          SQLCODE[1]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[1])+') ';
          SQLCODE[2]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[2])+') ';
          SQLCODE[3]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[3])+') ';
          SQLCODE[4]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[4])+') ';
          SQLCODE[5]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[5])+') ';
          SQLCODE[6]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[6])+') ';
          SQLCODE[7]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[7])+') ';
          SQLCODE[8]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[8])+') ';
          SQLCODE[9]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[9])+') ';
          SQLCODE[10]:= 'and (Seminare.SID <> '+inttostr(SID_angemeldet[10])+') ';



         if SIDcounter = 1 then    SQL_code:= SQLCODE[1]  else
         if SIDcounter = 2 then SQL_code:= SQLCODE[1] + SQLCODE[2]  else
         if SIDcounter = 3 then SQL_code:= SQLCODE[1] + SQLCODE[2] + SQLCODE[3] else
         if SIDcounter = 4 then SQL_code:= SQLCODE[1] + SQLCODE[2] + SQLCODE[3] + SQLCODE[4] else
         if SIDcounter = 5 then SQL_code:= SQLCODE[1] + SQLCODE[2] + SQLCODE[3] + SQLCODE[4] + SQLCODE[5]else
         if SIDcounter = 6 then SQL_code:= SQLCODE[1] + SQLCODE[2] + SQLCODE[3] + SQLCODE[4] + SQLCODE[5] + SQLCODE[6] else
         if SIDcounter = 7 then SQL_code:= SQLCODE[1] + SQLCODE[2] + SQLCODE[3] + SQLCODE[4] + SQLCODE[5] + SQLCODE[6] + SQLCODE[7] else
         if SIDcounter = 8 then SQL_code:= SQLCODE[1] + SQLCODE[2] + SQLCODE[3] + SQLCODE[4] + SQLCODE[5] + SQLCODE[6] + SQLCODE[7] + SQLCODE[8]else
         if SIDcounter = 9 then SQL_code:= SQLCODE[1] + SQLCODE[2] + SQLCODE[3] + SQLCODE[4] + SQLCODE[5] + SQLCODE[6] + SQLCODE[7] + SQLCODE[8] + SQLCODE[9]else
         if SIDcounter = 10 then SQL_code:= SQLCODE[1] + SQLCODE[2] + SQLCODE[3] + SQLCODE[4] + SQLCODE[5] + SQLCODE[6] + SQLCODE[7] + SQLCODE[8] + SQLCODE[9] + SQLCODE[10] ;


//hier der kniffelige Teil...funktioniert nicht.
          adoquery1.Close;
        adoquery1.close;
      adoquery1.SQL.Clear;
      adoquery1.SQL.Add('SELECT distinct Seminare.SID, Seminare.Seminartitel, Seminare.Datum FROM Seminare INNER JOIN (Mitarbeiter INNER JOIN Anmeldungen ON Mitarbeiter.MID = Anmeldungen.MID) ON Seminare.SID = Anmeldungen.SID WHERE ((Mitarbeiter.MID)<>' +inttostr(Mitarbeiter)+')'+SQL_Code+' ORDER BY Seminare.SID)');
      adoquery1.open;
      while not adoquery1.eof do begin
        LI := Listview2.items.Add;
        LI.Caption := inttostr(adoquery1.FieldValues['SID']);
        LI.subitems.add(adoquery1.FieldValues['Seminartitel']);
        LI.subitems.add(datetostr(adoquery1.FieldValues['Datum']));

       adoquery1.next;
       end;
       adoquery1.close;

hoika 15. Apr 2009 10:29

Re: knifflige KriterienAbfrage einer Datenbank!
 
Hallo,

puh, machst du es dir schwer ... ;)


Benutze einen Left Join und prüfe per Is Null .


Alternative wäre ein SubSelect etwa so

SQL-Code:
Select Seminare.* From Seminare
Where Seminare.SID not in
  (Select Anmeldungen.SID From Anmeldungen Where Anmeldungen.MID=:MId)
Delphi-Quellcode:
ParamByName('MId').AsInteger:= Mitarbeiter;


Heiko

DeddyH 15. Apr 2009 10:35

Re: knifflige KriterienAbfrage einer Datenbank!
 
Richtig. Etwas ausführlicher (wir suchen alle Datensätze aus Tabelle1, die keine Entsprechung in Tabelle2 aufweisen):
SQL-Code:
SELECT A.* 
FROM Tabelle1 A
LEFT JOIN Tabelle2 B ON A.Pk = B.Fk
WHERE B.Fk IS NULL

mkinzler 15. Apr 2009 11:32

Re: knifflige KriterienAbfrage einer Datenbank!
 
Der Vollständigkeit halber könnte man erwähnen, dass es alternativ auch per Subselect möglich ist.

DeddyH 15. Apr 2009 11:33

Re: knifflige KriterienAbfrage einer Datenbank!
 
Das hat Heiko doch getan :gruebel:

mkinzler 15. Apr 2009 11:42

Re: knifflige KriterienAbfrage einer Datenbank!
 
Upps, ich scheine heute blind zu sein.


Alle Zeitangaben in WEZ +1. Es ist jetzt 08:05 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz