Neuigkeiten:

Wenn ihr euch für eine gute Antwort bedanken möchtet, im entsprechenden Posting einfach den Knopf "sag Danke" drücken!

Mobiles Hauptmenü

Problem mit Abfrage (WHERE)

Begonnen von Jimmy89, Juni 10, 2015, 10:51:27

⏪ vorheriges - nächstes ⏩

Jimmy89

Hallo,

folgendes Problem:
Ich habe 2 Tabellen, die über eine m:n Tabelle miteinander verknüpft sind.(Tabelle Kommission und Tabelle MaschinenModul). m:n Tabelle ist Tabelle KommissionModul.
Jede Kommission besitzt mehrere MaschinenModule.
Z.b.:
Kommission KR744.. besitzt: Einspeisung, PHM, Umsetzer, Transfertisch
Kommission KR743.. besitzt: Einspeisung, Umsetzer

Wenn ich nun eine Abfrage mache:
Select Kommission From (tblKommission AS A
INNER JOIN tblKommissionModul AS B
ON B.lngKommission = A.IDKommission)
INNER JOIN tblMaschinenModul AS C
ON C.IDMaschinenModul = B.lngMaschinenModul
WHERE C.MaschinenModul IN('Einspeisung','Umsetzer')
AND C.MaschinenModul NOT IN ('PHM','Transfertisch')

Ergebnis: Access zeigt  mir beide Kommission an, aber normalerweise sollte er dann gar keine anzeigen. Ich will eben NUR die haben die auch wirklich die beiden MaschinenModule besitzen und die anderen NICHT.

Ist das ein grundlegendes Access Problem oder mache ich hier irgendeinen Fehler?

Vielen Dank
Jimmy

ebs17

Das Problem ist: Deine Logik passt nicht mit der SQL-Logik zusammen.

Das IN-Konstrukt (alleine) erzeugt eine ODER-Verknüpfung der genannten Kriterien, keine UND-Verknüpfung. Auch kann ein Datensatz in der Verknüpfungstabelle nur jeweils einen Fremdschlüssel zu einem Kriterium enthalten, weshalb eine UND-Verknüpfung erst mit etwas Overhead erzeugt werden kann.

Dein Anliegen ist selbstverständlich lösbar. Stelle bitte eine Demo mit den genannten Tabellen ein, das würde Schreibarbeit für einen Vorschlag erleichtern.
Mit freundlichem Glück Auf!

Eberhard

Jimmy89

Ok verstehe ich. Weiß nur nicht wie ich das lösen soll.
Für Hilfe wäre ich sehr dankbar.
Hier mal eine TestDatenbank.(Zu groß für ForumUpload)
TestDB.accdb

Dank für deine Hilfe. ;)

Viele Grüße
Jimmy

MaggieMay

Hi,
ZitatZu groß für ForumUpload
üblicherweise werden die Dateien vor dem Upload gezippt.

Was die Abfrage betrifft, dies wäre eine Möglichkeit:
Select Distinct Kommission
From (tblKommission AS A
INNER JOIN tblKommissionModul AS B ON B.lngKommission = A.IDKommission)
INNER JOIN tblMaschinenModul AS C ON C.IDMaschinenModul = B.lngMaschinenModul
WHERE C.MaschinenModul IN('Einspeisung','Umsetzer')
AND Not Exists
    (Select Null From  (tblKommission AS A1
     INNER JOIN tblKommissionModul AS B1 ON B1.lngKommission = A1.IDKommission)
     INNER JOIN tblMaschinenModul AS C1 ON C1.IDMaschinenModul = B1.lngMaschinenModul
     Where  A1.IDKommission =  A.IDKommission AND C1.MaschinenModul  IN ('PHM','Transfertisch')
    )
Freundliche Grüße
MaggieMay

ebs17

Mein Vorschlag:
SELECT
   K.Kommission
FROM
   tblKommission AS K
WHERE
   K.IDKommission IN
      (
         SELECT
            KM.lngKommission
         FROM
            tblMaschinenModul AS M
               INNER JOIN tblKommissionModul AS KM
               ON M.IDMaschinenModul = KM.lngMaschinenModul
         WHERE
            M.MaschinenModul IN('Einspeisung', 'Umsetzer')
               AND
            NOT EXISTS
               (
                  SELECT
                     NULL
                  FROM
                     tblMaschinenModul AS M1
                        INNER JOIN tblKommissionModul AS KM1
                        ON M1.IDMaschinenModul = KM1.lngMaschinenModul
                  WHERE
                     M1.MaschinenModul IN('PHM', 'Transfertisch')
                        AND
                     KM1.lngKommission = KM.lngKommission
               )
GROUP BY
   KM.lngKommission
HAVING
   COUNT(*) = 2
      )
Mit freundlichem Glück Auf!

Eberhard

Jimmy89

ohje,
das sieht ja mit 3 Tabellen schon sehr komplex aus.
Ich werde das morgen beides mal austesten und euch
ein Feedback geben ob ich es wie gewünscht hinbekommen habe.

Vielen Dank schonmal.

Grüße Jimmy

MaggieMay

Ok, das hatte ich überlesen:
ZitatIch will eben NUR die haben die auch wirklich die beiden MaschinenModule besitzen und die anderen NICHT.
Das sollte sich aber auch mit meiner Variante lösen lassen:
Select A.Kommission
From (tblKommission AS A
INNER JOIN tblKommissionModul AS B ON B.lngKommission = A.IDKommission)
INNER JOIN tblMaschinenModul AS C ON C.IDMaschinenModul = B.lngMaschinenModul
WHERE C.MaschinenModul IN('Einspeisung','Umsetzer')
AND Not Exists
    (Select Null From  (tblKommission AS A1
     INNER JOIN tblKommissionModul AS B1 ON B1.lngKommission = A1.IDKommission)
     INNER JOIN tblMaschinenModul AS C1 ON C1.IDMaschinenModul = B1.lngMaschinenModul
     Where  A1.IDKommission =  A.IDKommission AND C1.MaschinenModul  IN ('PHM','Transfertisch')
    )
GROUP BY A.Kommission
HAVING Count(*) > 1



Freundliche Grüße
MaggieMay

Jimmy89

#7
Hallo,

funktioniert einwandfrei. Habe die SQL Query noch ein "wenig"
erweitert und mit dynamischen Elementen versehen.
Momentan sieht meine SQL Query folgendermaßen aus:
SELECT DISTINCT K.idkommission,
                K.kommission
FROM   (((tblkommission AS K
          INNER JOIN tblmaschinentyp AS MT
                  ON MT.idmaschinentyp = K.lngmaschinentyp)
         INNER JOIN tblmaschinenmodell AS MM
                 ON MM.idmaschinenmodell = K.lngmaschinenmodell)
        INNER JOIN tblmaschinentypmerkmal AS MTM
                ON MTM.lngmaschinentyp = MT.idmaschinentyp)
       INNER JOIN tblmaschinenmerkmal AS MV
               ON MV.idmaschinenmerkmal = MTM.lngmaschinenmerkmal
WHERE  K.idkommission IN(SELECT KM.lngkommission
                         FROM   tblmaschinenmodul AS M
                                INNER JOIN tblkommissionmodul AS KM
                                        ON M.idmaschinenmodul =  KM.lngmaschinenmodul
                         WHERE  MT.maschinentyp = 'Variopac Pro'
                                AND MM.maschinenmodell = 'FS-4'
                                AND M.maschinenmodul IN ('Einspeisung', 'AcoposMulti')
                                AND NOT EXISTS (SELECT NULL
                                                FROM   tblmaschinenmodul AS M1
                                        INNER JOIN tblkommissionmodul AS KM1
                                                ON M1.idmaschinenmodul =  KM1.lngmaschinenmodul
                                                WHERE  M1.maschinenmodul IN ('Vakuumpumpe')
                                                       AND KM1.lngkommission = KM.lngkommission)
                         GROUP  BY KM.lngkommission
                         HAVING Count(*) = 2) 

Leider ist diese SQL Query noch ziemlich langsam.(10-20 Sekunden)
Hat irgendwer noch Optimierungsvorschläge? ;)

Grüße
Jimmy

Jimmy89

Hallo,

so jetzt ist ein Fall eingetreten den ich zuvor nicht bedacht hatte.
Wenn das Feld NOT EXISTS(....WHERE M1.MaschinenModul IN(''))
leer bleibt, dann kriege ich einen Fehler.

Meine Lösung: Wenn alle MaschinenModule ausgewählt sind, dann entferne ich das NOT EXISTS.
Jedoch habe ich dann wieder das selbe Problem, dass durch das M.MaschinenModul IN('.....','...','....')
alle MaschinenModule ausgewählt werden, und nicht die Konfiguration, die ich wirklich erhalten will.
(IN() erzeugt eine ODER Veknüpfung.)

Hat hier jemand eine Idee, wie das zu lösen ist?

Vielen Dank.
Gruß
Jimmy