2010-12-20 8 views
0

Ich habe eine Abfrage in MS Access erstellt ein FULL OUTER JOIN und kombinieren die Ergebnisse zu simulieren, die in etwa wie folgt aussieht:MS Access SQL: Troubles UNION ALL mit einem LEFT Kombination JOIN

SELECT NZ(estimates.employee_id, actuals.employee_id) AS employee_id 
, NZ(estimates.a_date, actuals.a_date) AS a_date 
, estimates.estimated_hours 
, actuals.actual_hours 
FROM (SELECT * 
     FROM estimates 
     LEFT JOIN actuals ON estimates.employee_id = actuals.employee_id 
     AND estimates.a_date = actuals.a_date 
     UNION ALL 
     SELECT * 
     FROM estimates 
     RIGHT JOIN actuals ON estimates.employee_id = actuals.employee_id 
     AND estimates.a_date = actuals.a_date 
     WHERE estimates.employee_id IS NULL 
     OR estimates.a_date IS NULL) AS qFullJoinEstimatesActuals 

ich gespeichert habe Diese Abfrage als ein Objekt (nennen wir es qEstimatesAndActuals). Mein Ziel ist es, JETS qEstimatesAndActuals mit einer anderen Tabelle zu verlassen. Etwas wie folgt aus:

SELECT * 
FROM qJoinedTable 
LEFT JOIN (SELECT * 
      FROM labor_rates) AS rates 
ON qJoinedTable.employee_id = rates.employee_id 
    AND qJoinedTable.a_date BETWEEN rates.begin_date AND rates.end_date 

MS Access übernimmt die Syntax und führt die Abfrage, lässt aber Ergebnisse, die eindeutig in der Ergebnismenge sind. Ich frage mich, ob das Datumsformat irgendwie verloren gegangen ist, also habe ich ein FORMAT um das begin_date und das end_date platziert, um zu erzwingen, dass sie als Short Dates interpretiert werden. Seltsamerweise erzeugte dies eine andere Ergebnismenge, aber es fehlte immer noch das Ergebnis, das es nicht haben sollte.

Ich frage mich, ob die Abfragen so durchgeführt werden, dass Sie die Ergebnismenge eines UNION ALL nicht VERBINDEN können. Hat jemand irgendwelche Gedanken/Ideen dazu? Gibt es einen besseren Weg, das Endziel zu erreichen?

Antwort

0

Übereinstimmend mit dem seltsamen Verhalten im Zusammenhang mit den Daten, stellte sich heraus, dass dieses Problem mit der Verwendung von NZ zusammenhing, um ein Datum aus qFullJoinEstimatesActuals auszuwählen. Die Verwendung von NZ scheint den Datentyp mehrdeutig zu machen. Als solches bewirkt die folgende Zeile aus dem Beispiel in meinem Beitrag den Fehler:

, NZ(estimates.a_date, actuals.a_date) AS a_date 

vieldeutigem Datentyp a_date verursacht dem Zwischen-Operator zu fehlerhaften Ergebnissen zu führen, wenn a_date Vergleichen der in der rates.begin_date und rates.end_date LINKE VERBINDUNG. Das Problem wurde durch Art Gießen das Ergebnis der NZ-Funktion aufgelöst, wie folgt:

, CDate(NZ(estimates.a_date, actuals.a_date)) AS a_date 
+0

Ich war auch frustriert über die Unzuverlässigkeit von Rückgabetypen mit Nz(), aber per Definition erwarten Sie, dass eines der Argumente mindestens zeitweise Null ist, was bedeutet, dass die Funktion bei der Rückgabetyp oder untersuchen Sie Metadaten zu den Quelldaten. Also musst du es selbst machen. Ein Join für einen Nz() - Ausdruck erscheint mir jedoch problematisch, da er keine Indizes verwenden kann. –

+0

Der Artikel basiert auf UNION ALLEN, was sinnvoll ist. Du hast nur einen. Wie können Sie alle Ergebnisse erhalten? – IamIC

+0

@ David-W-Fenton Das macht sicherlich Sinn. Was das Design betrifft, haben Sie einen anderen Vorschlag? Mit einer leichten Vereinfachung gibt es zwei Tabellen: (1) eine Schätztabelle mit einer Mitarbeiter_ID, einer Woche_End_Datum und der projizierten_Stunden und (2) eine Ist-Tabelle mit einer Mitarbeiter_ID, einem Wochenend_Datum und den tatsächlichen_Stunden. Es kann Mitarbeiter geben, die projiziert werden zu arbeiten, aber nicht. Ebenso kann es Mitarbeiter geben, die nicht auf die Arbeit vorbereitet wurden, aber es tun. Ziel: Holen Sie Mitarbeiter_ID, Wochenenddatum, projizierte_Stunden, aktuelle_Stunden in ein einzelnes abfragbares Objekt. ZB: 001, 9/26/2010, 0, 10 – Adam

0

Sie finden genau, wie Sie dies tun here.

Sie vermissen einen INNEREN JOIN .... UNION ALLE Schritt.

+0

Der Artikel, den Sie verwiesen haben wurde für die FULL als Grundlage JOIN (obwohl ich die Syntax modifiziert, um die Redundanz der Verwendung der entfernen INNER JOIN - wie einige von denen, die den Artikel kommentiert haben, könnten getan werden. Die Syntax zum Erstellen eines FULL JOIN ist jedoch * nicht * das Problem, das ich habe. Das Problem, das ich oben beschrieben habe, bezieht sich auf die Ergebnismenge, die erzeugt wird, wenn die Ergebnismenge des FULL JOIN (die selbstständig arbeitet) mit einem LINKEN JOIN kombiniert wird. – Adam

+0

Werfen Sie einen Blick auf das Venn-Diagramm aus dem Artikel.Während der Artikel geschrieben wird, verwendet der Autor drei Abfragen, um Set 1 (INNER JOIN), Set 2 (LEFT JOIN mit einer WHERE-Klausel zum Entfernen von Resultaten von Set 1) und Set 3 (RIGHT JOIN mit einer WHERE-Klausel zum Entfernen von Set 1) zu erhalten Ergebnisse) und verwendet zwei UNION ALLs, um sie zu kombinieren. Dies kann einfacher erreicht werden, indem zwei Abfragen verwendet werden, die erste zum Erhalten der Mengen 1 und 2 (LEFT JOIN * ohne * eine WHERE-Klausel zum Entfernen der Ergebnisse von Set 1) und die zweite zum Abrufen von 3 (RIGHT JOIN mit einer zu entfernenden WHERE-Klausel) Setze 1 Ergebnisse) und verwende eine UNION ALL um sie zu kombinieren. – Adam

+0

@Adam danke. Warum verwenden Sie aus Neugier nicht SQL Server? – IamIC

1

Ich würde versuchen, jeden Teil der Abfrage in sein eigenes Zugriffsabfrageobjekt, z.

SELECT * 
    FROM estimates 
    LEFT JOIN actuals ON estimates.employee_id = actuals.employee_id 
    AND estimates.a_date = actuals.a_date 

Würde

SELECT * 
    FROM estimates 
    RIGHT JOIN actuals ON estimates.employee_id = actuals.employee_id 
    AND estimates.a_date = actuals.a_date 
    WHERE estimates.employee_id IS NULL 
    OR estimates.a_date IS NULL 

sein qryOne wäre qryTwo

SELECT * FROM qryOne 
UNION ALL 
SELECT * FROM qryTwo 

qryFullJoinEstimatesActuals würde, und schließlich

SELECT NZ(estimates.employee_id, actuals.employee_id) AS employee_id 
, NZ(estimates.a_date, actuals.a_date) AS a_date 
, estimates.estimated_hours 
, actuals.actual_hours 
FROM qryFullJoinEstimatesActuals 

ich gefunden habe, dass Konstrukte, die nicht tun arbeiten in komplexen Access S QL-Anweisungen funktionieren oft richtig, wenn sie in einzelne Abfrageobjekte zerlegt und Schritt für Schritt neu zusammengesetzt werden. Darüber hinaus können Sie jeden Teil der Abfrage einzeln testen. Dies wird Ihnen helfen, einen Workaround zu finden, wenn sich dies als notwendig erweist.

+0

Danke für den Tipp. Obwohl dies nicht das Grundproblem war, brachte es mich (a) dazu, über einen anderen nicht zusammenhängenden Fehler zu stolpern, der später ein Problem gewesen wäre, und (b) half dabei, mich darauf zu konzentrieren, was das Problem verursacht hat. – Adam