collapse

* Benutzer Info

 
 
Willkommen Gast. Bitte einloggen oder registrieren. Haben Sie Ihre Aktivierungs E-Mail übersehen?

* Wer ist Online

  • Punkt Gäste: 59
  • Punkt Versteckte: 2
  • Punkt Mitglieder: 2

Es sind keine Mitglieder online.

* Forenstatistik

  • stats Mitglieder insgesamt: 13978
  • stats Beiträge insgesamt: 66559
  • stats Themen insgesamt: 8972
  • stats Kategorien insgesamt: 5
  • stats Boards insgesamt: 17
  • stats Am meisten online: 415

Autor Thema: Kunden auslesen, welche nicht ware von einem Lieferanten bekommen haben.  (Gelesen 6187 mal)

Guido

  • Gast
Ich habe folgendes Problem.

Ich habe eine Datenbank mit mehreren tabellen unter anderem die Tabellen " Kundenadressen", "Auftrag" und "Auftragdetail"
diese sind mit einer Beziehung verknüpft.

Jetzt sollte ich für eine MArketing aktion alle Kunden haben, welche noch nicht von dem einen Hersteller waren bekommen haben.

Bis jetzt habe ich eine Abfrage erstellt. mit Feldern aus allen drei Tabellen. mit der Bedingung  [Auftragsdetail]![Lieferantennr]<> 4
jetzt zeigt es mir aber die Kunden mehrfach an, weil sie ja mehrere Artikeldetails auch von anderen Herstellern bekommen haben. und es zeigt  auch die an, welche bereits von diesem bekommen haben.
Wie kann ich die Kunden drausen halten, welche im gleichen oder auch in anderen Aufträgen von diesem Hersteller Ware bekommen haben.
 

Offline database

  • Moderator
  • Access Guru
  • *****
  • Beiträge: 4178
Guten Morgen,

ich versuchs halt mal...

SELECT DISTINCT K.Feld1, K.Feld2, K.Feld3 FROM Kundenadressen K
      INNER JOIN Auftrag A ON A.KundenID = K.KundenID
      WHERE A.AuftragsID NOT IN(SELECT AuftragsID FROM Auftragdetail WHERE LieferantenNr =4)

Damit solltest du alle jene Kunden einfach angezeigt erhalten, bei deren Aufträgen der Lieferant 4 nicht vorkommt.

HTH
Peter
Viele Grüße
Peter

Tipps und Links:
---------------------------------------------------------
1. http://www.donkarl.com
2. http://www.access-entwicklerbuch.de/2007/index.php?page=buch
3. http://www.xlam.ch/pos/rules.htm
3.a Reservierte Worte
4. http://www.functionx.com/vbaccess/index.htm
5. http://www.dbwiki.net

Nicht vergessen: Jede(r) hat mal klein angefangen!
Bitte keine Fragen per PN senden - Fragen gehören ins Forum!
 

Guido

  • Gast
Danke für die schnelle antwort ich propiers mal heut abend.

LG Guido
 

Offline Hondo

  • Administrator
  • Access Guru
  • *****
  • Beiträge: 4641
  • Balu
    • Access Hilfe
Hallo,
Not In ist bei vielen Datensätzen ein "Performancefresser".
Besser ist wie bei Donkarl beschrieben:
http://www.donkarl.com/?FAQ3.16

Andreas
« Letzte Änderung: Mai 07, 2010, 12:22:18 von Hondo »
 

Offline database

  • Moderator
  • Access Guru
  • *****
  • Beiträge: 4178
Hallo,

Naja - also die Sache mit der Performance ist zweifelsfrei kritisch aber in Erwartung, dass die Abfrage nicht allzu oft ausgeführt werden wird (so schien es mir in der Frage) KANN man den Performance-Verlust verkraften - denke ich.
Zu Donkarls Tip - vielleicht habe ich jetzt nicht lange genug darüber gegrübelt aber ich sehe hier keinen direkten Tabellenvergleich und bis ein Konstrukt erzeugt ist, welches dann diese Vergleichsmöglichkeit bietet, ist die Abfrage auch schon durchgelaufen  :)
Aber technisch gesehen hast zweifelsohne recht Andreas!

Peter

Viele Grüße
Peter

Tipps und Links:
---------------------------------------------------------
1. http://www.donkarl.com
2. http://www.access-entwicklerbuch.de/2007/index.php?page=buch
3. http://www.xlam.ch/pos/rules.htm
3.a Reservierte Worte
4. http://www.functionx.com/vbaccess/index.htm
5. http://www.dbwiki.net

Nicht vergessen: Jede(r) hat mal klein angefangen!
Bitte keine Fragen per PN senden - Fragen gehören ins Forum!
 

Offline Hondo

  • Administrator
  • Access Guru
  • *****
  • Beiträge: 4641
  • Balu
    • Access Hilfe
Also ich hatte in einem Projekt einen Datenimport der eine halbe Stunde lief, je nach importierten Datensätzen.
Nach Umstellen der Queries von not In nach Is Null dauerte dieser nur noch ca. 20 Sekunden.
 

Josef

  • Gast
Hallo!

Noch eine Anmerkung bezüglich Geschwindigkeit:
"Not in (..)" ist vor allem dann langsam, wenn der Select-Teil, der in IN(...) steht, viele DS zurück liefert. Solange nur wenige DS im In-Ergebnis vorkommen, ist das normalerweise relativ flott.
Ich vermute, dass dabei zuerst der IN-Teil ausgewertet wird und dann per cross join vergleichen wird. Leider lässt sich mit dem Jet-Showplan nicht herausfinden, was dabei genau passiert.

Manchmal hilft bereits die umgestrickte Variante auf "Not Exists".

z. B.:
.... WHERE NOT EXISTS (SELECT * FROM Auftragdetail X WHERE X.LieferantenNr = 4 AND X.AuftragsID = A.AuftragsID)

Am schnellsten ist bei Jet aber immer die Left-Join-Variante mit NULL-Prüfung, wie in FAQ 3.16 gezeigt. Bei dieser gelingt dem Jet-Abfrageoptimierer die Gestaltung eines besseren Ausführungsplans.

Für das obige Beispiel wäre das dann:
SELECT
  ....
FROM
    (Kundenadressen K
    INNER JOIN
    Auftrag A
    ON A.KundenID = K.KundenID)
    LEFT JOIN
    Auftragdetail AD
    ON (AD.AuftragsID  = A.AuftragsID  AND AD.LieferantenNr =4)

Diese SQL-Anweisung kann allerdings wegen dem Verknüpfungsausdruck nicht mehr in der Entwurfsansicht dargestellt werden.
Falls jemand lieber mit der Entwurfsansicht arbeitet, wäre folgendes gleichwertig:
SELECT
  ....
FROM
    (Kundenadressen K
    INNER JOIN
    Auftrag A
    ON A.KundenID = K.KundenID)
    LEFT JOIN
    (Select AuftragsID FROM Auftragdetail where LieferantenNr = 4) as AD
    ON AD.AuftragsID  = A.AuftragsID
Das sollte den gleichen Ausführungsplan erzeugen und lässt sich im Entwurfsmodus darstellen.


BTW: falls jemand auch mit dem MSSQL-Server arbeitet: dort ist der Abfrageoptimierer auch bei der IN-Anweisung so schlau, dass er sie nach Bedarf in eine Exists-Variante umformuliert. Dabei kann es dann je nach Datensituation dazu führen, dass alle 3 Varianten den gleichen Ablaufplan erhalten.


mfg
Josef
 

Offline DF6GL

  • Global Moderator
  • Access-Oberguru
  • *****
  • Beiträge: 23349
Hallo Josef,


super.. Dank von meiner Seite für die Erklärungen  :)

Offline database

  • Moderator
  • Access Guru
  • *****
  • Beiträge: 4178
Morgääähn,

darf mich dem Dank von DF6GL anschließen...

LG

Peter
Viele Grüße
Peter

Tipps und Links:
---------------------------------------------------------
1. http://www.donkarl.com
2. http://www.access-entwicklerbuch.de/2007/index.php?page=buch
3. http://www.xlam.ch/pos/rules.htm
3.a Reservierte Worte
4. http://www.functionx.com/vbaccess/index.htm
5. http://www.dbwiki.net

Nicht vergessen: Jede(r) hat mal klein angefangen!
Bitte keine Fragen per PN senden - Fragen gehören ins Forum!
 

Offline Guido

  • Newbie
  • Beiträge: 2
Super antworten danke. leder bin ich in SQL ein blutiger Anfänger und habe es nciht geschaft ohhne Fehlermeldungen

ich habe folgendes eingesetzt

SELECT Kundenadresse.Anrede, Kundenadresse.Vorname, Kundenadresse.Name, Kundenadresse.Strasse, Kundenadresse.Land, Kundenadresse.Postleitzahl, Kundenadresse.Ort, Auftrag.Kundenummer, Auftrag.Bestelldatum
FROM (Kundenadresse INNER JOIN Auftrag ON Kundenadresse.Kundennummer = Auftrag.Kundenummer)
LEFT JOIN     
(Select Auftrag.Auftragsnummer FROM Auftragsdetail where LieferantenNr = 2)
as Auftragsdetail  ON Auftragsdetail.Auftragsnummer  =  Auftrag.Auftragsnummer;

Bi Wechseln in die Ansicht fragt er mich nun nach den Parameterwerten von Auftrag.Auftragsnummer und LieferantenNr obwohl beide Felder vorhanden sind.
ich checks nicht
Lg Guido