PDA

Vollständige Version anzeigen : Frage zu SQL


Michi
24.07.2001, 20:46
Hallo!
Ich habe ein HF namens 1 und ein UF namens 2. In 1 werden die Kunden gespeichert in 2 die Ansprechpartner (1:2 verknüpft). Mit der untenstehenden SQL frage ich nach allen Kunden, bei denen ein Ansprechpartner vorhanden ist (2 also gefüllt ist) UND nach allen Kunden, bei denen noch kein Ansprechpartner erfaßt ist (also 2 leer ist). Wie man sieht, läuft das ganze über eine UNION-Abfrage. Wie kann ich es jetzt hinbekommen, dass meine Abfrage auf Werte aus der Tabelle 2 auswirft. Ich will z. B. aus 2 das Feld Name und Vorname erhalten, auch wenn dieses leer ist. Trage ich das oben unter SELECT und unter FROM ein, zeigt mir Access Syntaxfehler an. Wie muß ich sowas einfügen? Vielen Dank! Hier nun die SQL:

(SELECT [1].Kundennummer,[1].Firma1,[1].Firma2,[1].Straße,[1].PLZ,[1].Ort,[1].Kategorie,[1].Name,[1].Kontaktverzicht
FROM (1 INNER JOIN 2 ON [1].Kundennummer = [2].Kundennummer)
WHERE (Exists (select Kundennummer from [2] where [1].Kundennummer=[2].Kundennummer AND [1].WGA And [2].Anschreiben)=True)) UNION (SELECT [1].Kundennummer,[1].Firma1,[1].Firma2,[1].Straße,[1].PLZ,[1].Ort,[1].Kategorie,[1].Name,[1].Kontaktverzicht FROM 1 WHERE (Exists (select Kundennummer from [2]
where [1].Kundennummer=[2].Kundennummer)=False) And [1].WGA=True);

A.S.
24.07.2001, 22:44
Hallo Michi,

ich kopiere Deine Anfrage - trotz des Access-Bezugs - einmal in das SQL-Forum von Achim.

Gruß

Arno

Michi
25.07.2001, 07:18
Das UF ist mit dem HF natürlich 1:n verknüpft und nicht 1:2! Herr, schmeiß Hirn vom Himmel!

Joachim Hofmann
25.07.2001, 09:24
Ich habe das nur mal flüchtig überlesen, noch nicht verstanden, aber es so formatiert, damit es besser lesbar ist.

Außerdem ist es immer günstig, die genaue Fehlermeldung mit zu schreiben.

Gruß
Achim

(
SELECT [1].Kundennummer,
[1].Firma1,
[1].Firma2,
[1].Straße,
[1].PLZ,
[1].Ort,
[1].Kategorie,
[1].Name,
[1].Kontaktverzicht
FROM
(
1 INNER JOIN 2
ON [1].Kundennummer = [2].Kundennummer
)
WHERE (
Exists (select Kundennummer from [2] where [1].Kundennummer=[2].Kundennummer AND [1].WGA And [2].Anschreiben)=True)
) -- Ende SELECT 1
UNION (
SELECT [1].Kundennummer,
[1].Firma1,
[1].Firma2,
[1].Straße,
[1].PLZ,
[1].Ort,
[1].Kategorie,
[1].Name,
[1].Kontaktverzicht
FROM 1
WHERE
(
Exists (select Kundennummer from [2] where [1].Kundennummer=[2].Kundennummer)=False
)
And [1].WGA=True
); -- Ende SELECT 2

Michi
25.07.2001, 10:43
Hallo Joachim!
Zunächst vielen Dank für Deine Hilfe. Der exakte Wortlaut der Fehlermeldung war: Syntaxfehler (fehlender Operator) und dann wurde mein gesamter SQL-Text nochmal wiedergegeben. Gruß, Michi

Michi
25.07.2001, 15:52
Ich habe zwischenzeitlich meine SQL wie folgt geändert. Leider bekomme ich immer die Aufforderung: "Parameterwerte eingeben" für die Felder 2.Name und 2.Vorname usw. für alle Felder aus der Tabelle 2. Kann das daran liegen, daß diese Felder bei manchen Kunden nicht gefüllt sind? Wie kann ich das ändern? Vielen Dank! Hier nun meine SQL:

(SELECT [1].Kundennummer,
[1].Firma1,
[1].Firma2,
[1].Straße,
[1].PLZ,
[1].Ort,
[1].Kategorie,
[1].Name,
[1].Kontaktverzicht,
[1].WGA,
[2].Name,
[2].Vorname,
[2].Titel,
[2].Anrede,
[2].Anschreiben
FROM
(1 INNER JOIN 2 ON [1].Kundennummer = [2].Kundennummer)
WHERE
( [1].WGA And [2].Anschreiben)=True)
UNION
(SELECT [1].Kundennummer,
[1].Firma1,
[1].Firma2,
[1].Straße,
[1].PLZ,
[1].Ort,
[1].Kategorie,
[1].Name,
[1].Kontaktverzicht,
[1].WGA,
[2].Name,
[2].Vorname,
[2].Titel,
[2].Anrede,
[2].Anschreiben
FROM
1
WHERE
(Exists (select Kundennummer from [2]
where [1].Kundennummer=[2].Kundennummer)=False)
And [1].WGA=True);

Joachim Hofmann
25.07.2001, 17:01
Hallo Michi,

mit Unterformularen beschäftige ich mich leider zu wenig. Wenn ich mich recht erinnere, kann man in den Eigenschaften ein Feld des UF mit einem Feld des HF verknüpfen und das war es.
In einer "gewöhnlichen" Access-Abfrage kann man für deinen gewünschten Fall auf die Verbindunglinie zwischen zwei Tabellen rechtsklicken und auswählen z.B. "Alle Zeilen aus Tabelle_2 UND Zeilen, in denen die Felder beider Tabellen gleich sind". Ob man so etwas auch mit einem UF hinbekommt, weiß ich nicht.
Wenn sowas nicht geht, bleibt vermutlich nichts, als das UF gar nicht verknüpfen sondern nur mit einer Abfrage hinterlegen, die sich mit einem Parameter auf ein (ev. unsichtbares) Feld Kundennummer im Hauptformular bezieht, und dann die Eigenschaft Recordsource (die Abfrage) des UF neu setzen, wenn man im HF den Datensatz ändert.

Das mit deinen UNIONs habe ich nicht verstanden, die scheinen mir für so einen Falle eigentlich gar nicht sinnvoll. Konstruiere im Entwurfsmodus mit den beiden Tabellen eine Abfrage für das Unterformular wie oben beschrieben und füge als Parameter ein Feld des HF ein.

Michi
25.07.2001, 19:26
Hier nochmal Details zu meinem Problem:

Kurz zu meinen Beweggründen, warum ich überhaupt auf eine UNION-Abfrage zurückgreife.

Hintergrund ist, dass ich an mehrere Kunden den gleichen Brief schicken will.
Meine Firmen werden in der Tabelle 1 (so heißt auch das Formular), meine einzelnen Ansprechpartner in der Tabelle 2 (Formular heißt ebenso) verwaltet. Das UF ist dem HF 1:n untergeordnet.

Meinen Brief soll nun jede Firma erhalten, die das Merkmal WGA=Ja (als Kontrollkästchen) hat. Eigentlich simpel, denn ich müßte nur nach allen Firmen mit diesem Kennzeichen abfragen. Jetzt jedoch das "Sahnehäubchen": Ist unter 2 ein Ansprechpartner gespeichert, soll nur der Ansprechpartner diesen Brief bekommen, der wiederum das Merkmal Anschreiben=Ja hat.

Man pickt sich also bei der Firma Eierservice GmbH nur den Herrn Huber als Empfänger heraus; der Meier und der Müller sollen kein Schreiben bekommen.

Ist hingegen überhaupt kein Ansprechpartner gespeichert (Kriterium exists([1].Kundennummer=[2].Kundennummer)=False), dann soll der Empfänger
pauschal die Geschäftsführung sein. Ein genauer Empfänger mit Namen ist ja nicht bekannt.

Ich habe mir also gedacht, ich brauche

- eine Abfrage, die die Felder Firma, Name, Vorname abfragt, wo das Kriterium WGA und Anschreiben "Ja" ist, und

- eine Abfrage, die alle Firmen heraussucht, bei denen überhaupt kein Ansprechpartner gespeichert ist, aber das Kriterium WGA "Ja" erfüllt ist

Ich habe so eine ähnliche Konstruktion schon Mal gebaut. Fazit: Access verkraftet keine "zweigleisige" Abfrage in einer normalen Abfrage. Ständig haben Datensätze, auf denen das Kriterium zutraf gefehlt.

Lösung deshalb, nach langem hin und her im Forum: Eine UNION-Abfrage muß her, die die Ergebnisse beider Abfragen vereint.

Meiner Meinung nach, läßt sich das Problem also nur über eine UNION-Abfrage lösen. Leider bin ich aber in SQL nicht besonders geübt. Wenn ich also bei meiner Abfrage nicht nur Felder aus der Tabelle 1 haben will, sondern auch aus 2, dann gibts bei mir Probleme. Ich habe die Felder (wie man bei meiner SQL sieht) nämlich einfach nur hinter SELECT eingefügt, bei FROM jedoch nicht. War das ein Fehler? Wie soll ich es anders lösen? Für meinen späteren Serienbrief brauche ich nämlich auch (falls vorhanden) die Namen der Ansprechpartner.
Ist kein Ansprechpartner erfaßt, soll die Abfrage trotzdem die Firma ausspucken.
Die Felder Name, Vorname usw. sollen dann eben leer sein. Ich werde dann über ein berechnetes Feld (mit Wenn=0, dann...) steuern, daß der Empfänger dann "z. Hd. der Geschäftsführung" heißt.

Wie mache ich das? Vielen Dank im voraus!

MarioR
25.07.2001, 20:36
Hallo Michi,

Acc fragt nach Parameterwerten, weil es für den 2. Teil der Union-Abfrage keine Daten aus einer Tabelle ziehen kann. Es findet die Felder Name, Vorname, ... ja nicht, da es dafür keinen DS in der Tab 2 gibt. Also musst Du Acc Daten für diese Felder liefern. Der SQL-String müsste demnach so aussehen:

(SELECT [1].Kundennummer,
[1].Firma1,
[1].Firma2,
[1].Straße,
[1].PLZ,
[1].Ort,
[1].Kategorie,
[1].Name,
[1].Kontaktverzicht,
[1].WGA,
[2].Name,
[2].Vorname,
[2].Titel,
[2].Anrede,
[2].Anschreiben
FROM
(1 INNER JOIN 2 ON [1].Kundennummer = [2].Kundennummer)
WHERE(
Exists (select Kundennummer from [2] where [1].Kundennummer=[2].Kundennummer AND [1].WGA And [2].Anschreiben)=True)
UNION
(SELECT [1].Kundennummer,
[1].Firma1,
[1].Firma2,
[1].Straße,
[1].PLZ,
[1].Ort,
[1].Kategorie,
[1].Name,
[1].Kontaktverzicht,
[1].WGA,
Null AS Name,
Null AS Vorname,
Null AS Titel,
Null AS Anrede,
Null AS Anschreiben
FROM
1
WHERE
(Exists (select Kundennummer from [2]
where [1].Kundennummer=[2].Kundennummer)=False)
And [1].WGA=True);

Die Felder Name, Vorname, Titel, Anrede und Anschreiben erhalten also für den 2. Teil der Abfrage Null als Wert. Da kannst Du natürlich auch was anderes übergeben, z.B. "z. Hd. der Geschäftsführung". Damit sparst Du Dir die anschliessende Auswertung der Felder.

Ob allerdings Deine Kriterien stimmen hab ich jetzt nicht überprüft.

Michi
26.07.2001, 11:10
Es funktioniert!!!
Access fragt jetzt nicht mehr nach irgendwelchen Parametern!

Vielen Dank an alle, besonders an Marco!