2009-07-17 4 views
0

Ich habe zwei Tabellen, jeweils mit drei booleschen (ms-Zugriff "Ja/Nein") Spalten.Join auf mehrere booleans

Tabelle 1: A1, B1, C1

Tabelle 2: A2, B2, C2

I eine bestimmte Zeile aus Tabelle 1, die die folgenden Bedingungen erfüllen, um die Zeilen aus der Tabelle 2 angegeben möchte:

Wenn A1 wahr ist, dann nur Zeilen, bei denen A2 wahr ist, wenn A1 falsch ist, dann Zeilen, bei denen A2 wahr oder falsch ist. Wenn B1 wahr ist, dann nur Zeilen, bei denen B2 wahr ist, wenn B1 falsch ist, dann Zeilen, bei denen B2 wahr oder falsch ist. Wenn C1 wahr ist, dann nur Zeilen, bei denen C2 wahr ist, wenn C1 falsch ist, dann Zeilen, bei denen C2 wahr oder falsch ist.

Beispiel eins

  A, B, C  
Table 1: 0, 1, 0 (selected row) 

Table 2: 1, 0, 0 
     0, 1, 0 (in return set) 
     1, 1, 0 (in return set) 
     0, 0, 1 
     1, 0, 1 
     0, 1, 1 (in return set) 
     1, 1, 1 (in return set) 

Beispiel Zwei

  A, B, C  
Table 1: 0, 0, 1 (selected row) 

Table 2: 1, 0, 0 
     0, 1, 0 
     1, 1, 0 
     0, 0, 1 (in return set) 
     1, 0, 1 (in return set) 
     0, 1, 1 (in return set) 
     1, 1, 1 (in return set) 

Wie kann ich das am besten erreichen?

Zum Beispiel funktioniert das nicht:

SELECT  vw_fbScheduleFull.LocationName, vw_fbScheduleFull.FieldName, vw_fbScheduleFull.Description, vw_fbScheduleFull.StartTime, 
         vw_fbScheduleFull.EndTime, vw_fbScheduleFull.LowerDivision, vw_fbScheduleFull.UpperDivision, vw_fbScheduleFull.SeniorDivision 
FROM   (vw_fbScheduleFull INNER JOIN 
         fbDivision ON vw_fbScheduleFull.LowerDivision = fbDivision.LowerDivision AND fbDivision.LowerDivision = 1 OR 
         vw_fbScheduleFull.UpperDivision = fbDivision.UpperDivision AND fbDivision.UpperDivision = 1 OR 
         vw_fbScheduleFull.SeniorDivision = fbDivision.SeniorDivision AND fbDivision.SeniorDivision = 1) 
WHERE  (vw_fbScheduleFull.PracticeDate = ?) AND (vw_fbScheduleFull.Locked IS NULL) AND (fbDivision.DivisionName = ?) 
ORDER BY vw_fbScheduleFull.LocationName, vw_fbScheduleFull.FieldName, vw_fbScheduleFull.StartTime 
+0

Ist das Hausaufgaben? – SingleNegationElimination

+0

Das sollte die nächste verwandte Website sein. domyhomework.com – Troggy

+0

Nein, das ist echt. Ich habe keine Hausaufgaben. Entschuldigung für die Vereinfachung des Beispiels. – Degan

Antwort

3

Es ist nicht wirklich ein Problem SQL Sie fragen, nur ein boolean Ausdruck Problem. Ich nehme an, Sie haben eine andere Spalte in diesen Tabellen bekommen, dass Sie die Zeilen in t1 bis t2 anschließen kann, aber im Anschluss an Ihre Beispielen (wo es nur 1 Zeile in t1), können Sie es als:

SELECT t2.A2 
     , t2.B2 
     , t3.C2 
    FROM t1 
     , t2 
    WHERE (t2.A2 OR NOT T1.A1) 
    AND (t2.B2 OR NOT T1.B1) 
    AND (t2.C2 OR NOT T1.C1) 
; 

Ich sehe jetzt die nicht abstrahierte Antwort, die Sie oben gepostet haben. Auf dieser Grundlage gibt es einige Probleme in Ihrem SQL. Zum einen sollten Sie nur die Bedingungen in Ihren JOIN-Klauseln ausdrücken, die die vw_fbScheduleFull-Tabelle mit der fbDivision-Tabelle verbinden (d. H. Die Fremd-/Primärschlüssel-Beziehung). Alle Sachen von LowerDivision/UpperDivision/SeniorDivision sollten sich in der WHERE-Klausel befinden.

Zweitens ignorieren Sie die Vorrangstellung der Operatoren AND und OR - Sie möchten jedes der * Division-Paare in Parens einschließen, um unerwünschte Effekte zu vermeiden.

nicht das volle Schema der Tabellen zu wissen, ich, dass die richtige Version dieser Abfrage in etwa so aussehen würde, würde vermuten:

SELECT vw_fbScheduleFull.LocationName 
     , vw_fbScheduleFull.FieldName 
     , vw_fbScheduleFull.Description 
     , vw_fbScheduleFull.StartTime 
     , vw_fbScheduleFull.EndTime 
     , vw_fbScheduleFull.LowerDivision 
     , vw_fbScheduleFull.UpperDivision 
     , vw_fbScheduleFull.SeniorDivision 
    FROM vw_fbScheduleFull 
     , fbDivision 
    WHERE vw_fbScheduleFull.PracticeDate = ? 
    AND vw_fbScheduleFull.Locked IS NULL 
    AND fbDivision.DivisionName = ? 
    AND (vw_fbScheduleFull.LowerDivision = 1 OR fbDivision.LowerDivision <> 1) 
    AND (vw_fbScheduleFull.UpperDivision = 1 OR fbDivision.UpperDivision <> 1) 
    AND (vw_fbScheduleFull.SeniorDivision = 1 OR fbDivision.SeniorDivision <> 1) 
ORDER BY vw_fbScheduleFull.LocationName 
     , vw_fbScheduleFull.FieldName 
     , vw_fbScheduleFull.StartTime 
; 

Suche noch einmal, merke ich, dass Ihr „fbDivision.DivisionName = " Wahrscheinlich wird die Anzahl der Zeilen in dieser Tabelle auf eins reduziert, und es gibt keine formale PK/FK-Beziehung zwischen diesen beiden Tabellen. In diesem Fall sollten Sie auf die INNER JOIN-Nomenklatur in der FROM-Klausel verzichten und nur die beiden Tabellen auflisten; Ich habe mein Beispiel aktualisiert.

+0

+ 1 für die vereinfachte Where-Klausel. –

+0

Es scheint zu funktionieren, nachdem ich die Abfrage mit der "OR NOT" -Syntax erstellt habe. Meine IDE (Visual Studio Express) organisiert meine SQL häufig neu, einschließlich des Löschens von Parens (wie in diesem Fall), oder öfter, indem ich einen ganzen Haufen von Unerlegten hinzufüge. Ich hatte viele non-JOIN-Wege versucht, um diese Filterung zu erreichen, aber irgendwie hatte mich überzeugt, dass ein JOIN erforderlich war. Vielen Dank für Ihre Hilfe. – Degan

0

Steve Brobergs Antwort ist richtig und gut; Ich würde nur hinzufügen, dass Aliase können Abfragen viel einfacher für die Augen machen:

SELECT f.LocationName 
     , f.FieldName 
     , f.Description 
     , f.StartTime 
     , f.EndTime 
     , f.LowerDivision 
     , f.UpperDivision 
     , f.SeniorDivision 
    FROM vw_fbScheduleFull f 
     , fbDivision  d 
    WHERE f.PracticeDate = ? 
    AND f.Locked IS NULL 
    AND d.DivisionName = ? 
    AND (f.LowerDivision = 1 OR d.LowerDivision <> 1) 
    AND (f.UpperDivision = 1 OR d.UpperDivision <> 1) 
    AND (f.SeniorDivision = 1 OR d.SeniorDivision <> 1) 
ORDER BY f.LocationName 
     , f.FieldName 
     , f.StartTime 
; 
+0

Das ist eine Antwort, die von jemandem kommt, der Access wahrscheinlich nicht verwendet, aber sein SQL von Hand schreibt. –

+0

In beiden Fällen korrigieren. Enthält Access 'SQL keine Aliase? –