[gelöst] einfache Lösung für SQL

4. November 2008 12:29

Hallo zusammen,

ich möchte gerne aus einer Tabelle alle Werte, die nicht in der anderen nach setzen eines Filters gefunden werden. Im reinen SQL wäre das ja so was wie "Select X from Tabelle1 where X NOT IN (Select X from Tabelle2)". Lässt sich so was einfach umsetzen oder muss ich erst dafür erst Tabelle 2 entsprechend filtern und dann die Daten daraus irgendwie zu einem Filter umbauen?
Zuletzt geändert von CaddyM am 13. November 2008 17:36, insgesamt 1-mal geändert.

Re: einfache Lösung für SQL " ....where X not in (select Y ...."

4. November 2008 16:21

Wenn du das nur einmal brauchst (und SQL-Server hast) kannst du dir das ja direkt im SQL-Server-Management-Studio angucken. Wenn du es öfter brauchst (und SQL-Server hast) kannst du dir eine View bauen und diese in Navision (als Tabelle) nachbauen. Sonst fällt mir auch nix ein als die Daten der Tabelle1 in einer temporären Kopie der Tabelle1 zwischenzuspeichern und dann die Datensätze zu löschen, die in Tabelle2 gefunden wurden. Ob diese Lösung praktikabel ist hängt sicher auch von der Anzahl der Datensätze ab. Falls es sich um viele Datensätze handelt und sich die Daten nicht zu oft ändern, kann man auch ne Kopie der Tabelle1 anlegen und diese mit den Triggern der Tabellen 1 und 2 aktuell halten.

Wenn ihr eine oder alle dieser Ideen für verwerflich haltet - bitte schreibt mir dies und auch warum. Ich möchte solche Fehler nicht 2 mal machen - auch wenn ich es in diesem Fall nicht persönlich ausbaden müsste.

Re: einfache Lösung für SQL " ....where X not in (select Y ...."

4. November 2008 16:46

Hallo,

das ginge auch - meine direkte Idee wäre ein Arrray gewesen - am Beispiel von Tabelle 1, die alles verarbeiten soll , was nicht über Tabelle 2 ausgeschlossen wird (Pseudocode):
Code:
// ****Array : Array für Personalnumern
// **** i: Zählvariable
Tabelle2.setfilter(Kriteriumsfeld, '=Ausschlusskriterium'):
if Tabelle2.findset(false) then begin
  i := 1;
  repeat
    Array[i] := Tabelle2."Personal Nummer";
    i += 1;
  until Tabelle1.next = 0;
end;


Im Anschluss habe ich dann ja alle, die ich nicht berücksichtigen will, die weitere Verarbeitung wäre dann (Pseudocode):

Code:
//***** j: zweite Zählvariable
// **** varSkip : Boolescher Wert
Tabelle1.setrange(Filterkriterium); //für die, die ich bearbeiten muss
if tabelle1.findset(false) then begin
    repeat
       varSkip := false;
       if i > 0 then begin
         for j := 1 to i do begin
           if NOT varskip then
             varskip := (Tabelle1."Personal Nummer" = Array[j];
         end;
       end;
       
       //Wenn keine Skipmarkierrung gesetzt ist, verarbeiten
       if not varSkip then begin
            ..............
            ..............
       end;       
  until Tabelle1.next = 0;
end;



Schade, ich hatte eigentlich gehofft dass es etwas einfacher geht - aber dann muss ich mir halt behelfen. Ich lass das Thema mal noch bis morgen offen, vielleicht hat ja jemand eine Lösung.

Danke jedenfalls :)

Re: einfache Lösung für SQL " ....where X not in (select Y ...."

4. November 2008 23:52

Hallo!

kannst du mal etwas genauer sagen, wie die Beziehungen zwischen den Tabellen sind, und wie groß das zu bearbeitende Datenvolumen ist. So kann man nicht genau sagen wie die günstigste Lösung ist.

  • man könnte evtl. mit einem Flowfield in der ersten Tabelle arbeiten, das true ist, wenn ein Datensatz in der zweiten Tabelle ist. Dan müsstest du nur noch auf das Flowfield filtern.
  • (Markedonly) Eine While- Schleife, die mit MARK alle Datensätze markiert, die nicht in der zweiten Tabelle drin sind
  • Benötigst du das ganze in einem Report, kann man mit Currreport.SHOWOUTPUT, Currreport.SKIP, Currreport.BREAK einiges bewirken, die abhängig von einem FIND oder GET gesteuert werden.

Gruß, Fiddi

Re: einfache Lösung für SQL " ....where X not in (select Y ...."

5. November 2008 17:15

Hallo Fiddi,

in Tabelle1 stehen Tagesdaten, täglich kommt ein oder mehrere Datensätze / Mitarbeiter hinzu.

In Tabelle2 stehen die Mitarbeiter, also eine gleichbleibende überschaubare Größe, und von denen haben auch nur ein paar dieses spezielle Merkmal, was einen Teil ihrer Daten aus Tabelle1 nicht für bestimmte Anzeigen notwendig macht (im moment sind davon ca. 8 Mitarbeiter betroffen).

Thema GET bzw FIND: das sind irgendwann zuviele Datenbankzugriffe - ich denke wirklich dass es performanter ist, die Personalnummern kurz auszulesen und zwischenzuspeichern und dann nur noch schnell in dem Array gucken. Wenn ich z.B. Monatsdaten muit GET / FIND auswerten würde, wären das pro Monat 20+ GETs / FINDs / Mitarbeiter ....

Re: einfache Lösung für SQL " ....where X not in (select Y ...."

5. November 2008 21:10

Hallo CaddyM

Kannst du das ganze nicht umdrehen? Wenn du die Mitarbeiter als führende Tabelle nimmst und entsprechend filterst, und danach die Tagesdaten als Subtabelle nimmst, die du zunächts statisch filterst und dann über die Mitarbeiternr. verlinkst. Welche Methode funktioniert, hängt im wesentlichen von der Schlüsselstruktur der beteiligten Tabellen ab. Evtl bringt auch ein Flowfield in der Tagestabelle, das die gewünschte Eigenschaft des Mitarbeiters holt, die Lösung. Auf dieses Flowfield kannst du dann filtern.

Gruß, Fiddi

Re: einfache Lösung für SQL " ....where X not in (select Y ...."

6. November 2008 13:11

Hallo Fiddi,

alternativ könnte ich es so machen:
1. Tabelle mit dem Filterkriterium ausfiltern
2. aus der Personalnummern einen Filterstring erstellen und damit die Tagesdatentabelle um einen Filter erweitern - das müsste eigentlich die eleganteste Lösung sein, weil imho alle Tabelle.SETRANGE und SETFILTER - Zeilen ja mit "Und" verknüpft sind. Der Filter sähe am Ende so aus:

Code:
Tabelle2.RESET;
Tabelle2.SETRANGE(Tabelle2.Filterkriterium, TRUE);
if Tabelle2.FINDSET(FALSE) then begin
  FilterString := FilterString + Personalnummer;
  .... Kommatas einfügen etc .....
end;

Tabelle1.RESET;
Tabelle1.SETRANGE ( ...);
..... weitere Filter

Tabelle1.SETFILTER(Tabelle1.Personalnr, 'NOT IN [%1]', FilterString);
if Tabelle1.findset then
..... Verarbeitung


Das müsste das Problem eigentlich am sinnvollsten lösen, oder?

Re: einfache Lösung für SQL " ....where X not in (select Y ...."

6. November 2008 20:59

Sicherlich nicht eine der performantesten Lösungen, aber wie wäre es mit einem Boolean FlowField (Exists) von Tabelle 1 auf Tabelle 2 und dann auch auf dieses Feld filtern? Würde dann sogar interaktiv funktionieren.

Re: einfache Lösung für SQL " ....where X not in (select Y ...."

13. November 2008 17:35

Ja, das geht. Muss ich an einigen Ecken noch feilen, aber sonst: Gelöst.