Supportnet / Forum / Datenbanken
Auschließen in Abfragen?
Frage
Hallo zusammen :)
Eine kleine Denksportaufgabe, an der ich gescheitert bin ... kann mir jemand helfen?
->
Ich möchte eine Tabelle mit 2 Spalten erstellen:
Lager (da haben wir die Lagerorte A, B, C) und Artikel (da haben wir die Artikel a, b, c, d, e). Jetzt kann es sein dass Artikel in mehreren Lagern vorkommen.
In der Tabelle wird später z.B. folgendes stehen:
[Artikel] [Lager]
a A
a B
b A
b C
c B
c C
d A
d B
d C
e B
Nun mein Problem: Ich brauche eine Abfrage die mir ALLE Artikel zeigt, die entweder in Lager B oder C vorkommen,(oder beiden Lagern B+C) NICHT aber in Lager A.
Wie mache ich das?
Im oberen Beispiel wären das also die Artikel [c, e] die dem Lager A fehlen in den anderen aber vorrätig sind.
Ich weiß net wie ich das machen soll...
---
Und ne kleine Zusatzfrage: Wenn ich dann in dem Formular für Lager A bin und ein Feld einfügen möchte wo ich Teile in das Lager hinzufügen kann, kann ich dann sagen er soll automatisch für diesen neuen Artikel in die Spalte [Lager] "A" eintragen?
Boa wäre klasse wenn mir da jemand helfen könnte! Ist ne Menge Text ich weiß ... großes Dankeschön schon jetzt :) ...ich hoffe mir ist noch zu helfen ;)
Gruuuß
ihr seid klasse!
Zeroo
Antwort 1 von Armin
hi, so würde ich hier vorgehen:
annahme:
du hast(besser: du brauchst) 3 tabellen:
tabelle "Artikel"
tabelle "Lager"
tabelle "ArtikelInLager" (also deine oben beschriebene ...)
die beziehungen der tabellen sind im editor festgelegt.
dann:
1. mit dem entwurfseditor für abfragen würde ich mir eine query zusammenstellen, die das tut was du willst [ZENS] problem: "ALLE Artikel zeigt, die entweder in Lager B oder C vorkommen,(oder beiden Lagern B+C) NICHT aber in Lager A.", hier im editor jede einzelne bedingung untereinander schreiben unter das feld "Lager").
damit hast du schon einmal den sql code für eine statische abfrage.
2. wahrscheinlich willst du die abfrage flexibel nach artikel / Lager durch den user haben.
3. Weg Nr. 1: so wie in der db, die ich dir geschickt hatte, ein Auswahlkriterium ermitteln (der inhalt des formfilters ist als sql string abrufbar) und mit der basis query von 1. per vba zusammenbauen und als filter des formulars setzen.
Weg Nr. 2: du definierst felder für Lager, NICHT Lager, Artikel etc. und modifizierst deinen sql string entsprechend per vba.
cu armin
annahme:
du hast(besser: du brauchst) 3 tabellen:
tabelle "Artikel"
tabelle "Lager"
tabelle "ArtikelInLager" (also deine oben beschriebene ...)
die beziehungen der tabellen sind im editor festgelegt.
dann:
1. mit dem entwurfseditor für abfragen würde ich mir eine query zusammenstellen, die das tut was du willst [ZENS] problem: "ALLE Artikel zeigt, die entweder in Lager B oder C vorkommen,(oder beiden Lagern B+C) NICHT aber in Lager A.", hier im editor jede einzelne bedingung untereinander schreiben unter das feld "Lager").
damit hast du schon einmal den sql code für eine statische abfrage.
2. wahrscheinlich willst du die abfrage flexibel nach artikel / Lager durch den user haben.
3. Weg Nr. 1: so wie in der db, die ich dir geschickt hatte, ein Auswahlkriterium ermitteln (der inhalt des formfilters ist als sql string abrufbar) und mit der basis query von 1. per vba zusammenbauen und als filter des formulars setzen.
Weg Nr. 2: du definierst felder für Lager, NICHT Lager, Artikel etc. und modifizierst deinen sql string entsprechend per vba.
cu armin
Antwort 2 von mapet
Hallo
Du hast weniger Probleme wenn du das ganze mi drei Tabellen löst.
t_lager
t_artikel
t_vt_lager_artikel
wobei vt eine verknüpfungstabelle n:m ist mit den jeweiligen Primärschlüsseln von Lager und Artikel
Interesse an der fertigen Lösung Mail an mich
Du hast weniger Probleme wenn du das ganze mi drei Tabellen löst.
t_lager
t_artikel
t_vt_lager_artikel
wobei vt eine verknüpfungstabelle n:m ist mit den jeweiligen Primärschlüsseln von Lager und Artikel
Interesse an der fertigen Lösung Mail an mich
Antwort 3 von Zeroo
Hi und danke für die Antworten!
Mapet, klar hätte ich Interesse an der fertigen Lösung, wenn es dir nicht all zu viele Umstände macht! Danke!!! Hab dich aber nicht per E-Mail erreicht ... er bringt mir da ne Fehlermeldung.
Meine ist: zerogrit@web.de
THX!!!
Zeroo
Mapet, klar hätte ich Interesse an der fertigen Lösung, wenn es dir nicht all zu viele Umstände macht! Danke!!! Hab dich aber nicht per E-Mail erreicht ... er bringt mir da ne Fehlermeldung.
Meine ist: zerogrit@web.de
THX!!!
Zeroo
Antwort 4 von Knubbel
Hallo Zeroo,
mein später Beitrag zu deinem Problem:
Zunächst denke ich, dass dies Problem etwas für VBA-Füchse ist. Da ich hiervon keine Ahnung habe und du nach einer "Abfrage"-Lösung suchst, hier mein Vorschlag:
Ausgehend von deiner Beispiel-Tabelle (Lager/Artikel) kreierst du zunächst die 3 Abfragen:
Lager A (Kriterium "A")= alle Artikel in Lager A
Lager B dto. mit Kriterium "B"
Lager C dto. mit Kriterium "C"
Nun erstellst du eine neue Abfrage "Artikel in allen Lägern". Als Datenquelle wählst du die 3 "Lager"-Abfragen.
Alle Felder übernehmen:
Lager A.Lager /Lager A.Artikel /Laber B.Lager /Lager B.Artikel ... usw.
Wichtig: Die Datenquellen-Abfragen dürfen nicht verknüpft sein!
Wenn du diese Abfage ausfühst, erhälst du alle Kombinationen der Artikel in den 3 Lägern. Nach deinem Beispiel also:
Lager A = 3 Artikel
Lager B = 4 Artikel
Lager C = 3 Artikel
= also 3*4*3 = 36 Kombinationen (virtuelle Datensätze)
Nun kommt die alles entscheidende Abfrage "fehlende Artikel in Lager A":
Als Datenqelle nimmst du vorherige Abfrage "Artikel in allen Lägern".
Hieraus übernimmst du nur das Feld "Artikel in allen Lägern.Lager A.Lager".
Funktion: Gruppierung
Nun fügst du für jeden der vorkommenden Artikel ein berechnetes Feld mit folgender Syntax an:
a fehlt: Max(Wenn([Lager A.Artikel]="a";"nein";"Ja"))
Funktion: Ausdruck
b fehlt: Max(Wenn([Lager A.Artikel]="b";"nein";"Ja"))
usw. für alle Artikel
Wenn du diese Abfage ausfühst, erhäst du mit deinen Beispieldaten folgendes Ergebnis:
Lager A.Lager / a fehlt / b fehlt / c fehlt / d fehlt / e fehlt
A / nein / nein / ja / nein / ja
Erläuterung zu der Funktion diese Abfrage:
Wenn die Abfrage ohne die Aggregatfunktion Max...
ausgeführt wird, werden alle 36 Kombinationen aus der Abfrage "Artikel in allen Lägern" auf Übereinstimmung geprüft und entweder "Ja" oder "nein" eingetragen (36 Datensätze mit 1 + 5 Datenfeldern).
Nur wenn ein Artikel bei allen Kombinationen fehlt, erscheint in allen 36 Datensätzen "Ja", sonst wechselhaft "Ja" und "nein".
Weil "nein">"Ja" wird die Agregatfunktion Max... eingesetzt in Kombination mit Gruppieren bei Lager.
Zugegeben, eine nicht einfach zu durchschauende Lösung des Problems und sicher nur sinnvoll bei wenigen Lägern und wenigen Artikeln.
mfg Knubbel
mein später Beitrag zu deinem Problem:
Zunächst denke ich, dass dies Problem etwas für VBA-Füchse ist. Da ich hiervon keine Ahnung habe und du nach einer "Abfrage"-Lösung suchst, hier mein Vorschlag:
Ausgehend von deiner Beispiel-Tabelle (Lager/Artikel) kreierst du zunächst die 3 Abfragen:
Lager A (Kriterium "A")= alle Artikel in Lager A
Lager B dto. mit Kriterium "B"
Lager C dto. mit Kriterium "C"
Nun erstellst du eine neue Abfrage "Artikel in allen Lägern". Als Datenquelle wählst du die 3 "Lager"-Abfragen.
Alle Felder übernehmen:
Lager A.Lager /Lager A.Artikel /Laber B.Lager /Lager B.Artikel ... usw.
Wichtig: Die Datenquellen-Abfragen dürfen nicht verknüpft sein!
Wenn du diese Abfage ausfühst, erhälst du alle Kombinationen der Artikel in den 3 Lägern. Nach deinem Beispiel also:
Lager A = 3 Artikel
Lager B = 4 Artikel
Lager C = 3 Artikel
= also 3*4*3 = 36 Kombinationen (virtuelle Datensätze)
Nun kommt die alles entscheidende Abfrage "fehlende Artikel in Lager A":
Als Datenqelle nimmst du vorherige Abfrage "Artikel in allen Lägern".
Hieraus übernimmst du nur das Feld "Artikel in allen Lägern.Lager A.Lager".
Funktion: Gruppierung
Nun fügst du für jeden der vorkommenden Artikel ein berechnetes Feld mit folgender Syntax an:
a fehlt: Max(Wenn([Lager A.Artikel]="a";"nein";"Ja"))
Funktion: Ausdruck
b fehlt: Max(Wenn([Lager A.Artikel]="b";"nein";"Ja"))
usw. für alle Artikel
Wenn du diese Abfage ausfühst, erhäst du mit deinen Beispieldaten folgendes Ergebnis:
Lager A.Lager / a fehlt / b fehlt / c fehlt / d fehlt / e fehlt
A / nein / nein / ja / nein / ja
Erläuterung zu der Funktion diese Abfrage:
Wenn die Abfrage ohne die Aggregatfunktion Max...
ausgeführt wird, werden alle 36 Kombinationen aus der Abfrage "Artikel in allen Lägern" auf Übereinstimmung geprüft und entweder "Ja" oder "nein" eingetragen (36 Datensätze mit 1 + 5 Datenfeldern).
Nur wenn ein Artikel bei allen Kombinationen fehlt, erscheint in allen 36 Datensätzen "Ja", sonst wechselhaft "Ja" und "nein".
Weil "nein">"Ja" wird die Agregatfunktion Max... eingesetzt in Kombination mit Gruppieren bei Lager.
Zugegeben, eine nicht einfach zu durchschauende Lösung des Problems und sicher nur sinnvoll bei wenigen Lägern und wenigen Artikeln.
mfg Knubbel
Antwort 5 von El Bobbele
Hallo zeroo!
Das kann mit einer Abfrage realisiert werden. Wenn du die Namen deiner betroffenen Tabelle und Felder nennst, dann bekommst du im Gegenzug eine fertige SQL-Anweisung.
Verwendest du bereits eine 3-Tabellenlösung, wie es Armin und mapet bereits beschrieben haben?
Gruss
El Bobbele
Das kann mit einer Abfrage realisiert werden. Wenn du die Namen deiner betroffenen Tabelle und Felder nennst, dann bekommst du im Gegenzug eine fertige SQL-Anweisung.
Verwendest du bereits eine 3-Tabellenlösung, wie es Armin und mapet bereits beschrieben haben?
Gruss
El Bobbele
Antwort 6 von Knubbel
@ El Bobbele
Auch wenn wir unterschiedliche Meinungen zu Makros haben, lass doch mal dein Wissen zu obigem Problem rüber kommen.
1) Was bringt die 3-Tabellen-Technik?
Lager --- Lager/Artikel --- Artikel
In der verknüpften Tabelle stehen die gleichen Angaben, wie in zeroo`s Ursprungstabelle.
2) Wie kann man in einer Abfrage "nicht übereinstimmen" herausfiltern?
Mach doch bitte mal detailierte Angaben, die auch für Laien (wie mich) nachvollziehbar sind.
mfg Knubbel
Auch wenn wir unterschiedliche Meinungen zu Makros haben, lass doch mal dein Wissen zu obigem Problem rüber kommen.
1) Was bringt die 3-Tabellen-Technik?
Lager --- Lager/Artikel --- Artikel
In der verknüpften Tabelle stehen die gleichen Angaben, wie in zeroo`s Ursprungstabelle.
2) Wie kann man in einer Abfrage "nicht übereinstimmen" herausfiltern?
Mach doch bitte mal detailierte Angaben, die auch für Laien (wie mich) nachvollziehbar sind.
mfg Knubbel
Antwort 7 von Knubbel
@ all,
ich bin kein Access-Profi und habe von VBA überhaupt keinen Schimmer (ich nutze meist die eingebauten Makro-Funktionen - Ich stehe hier im eingeschschränkten Widerspruch zu El Bobbele -)
Aber, bitte erklärt mir mal, wie Hilfesuchende solche Vorschläge verstehen (übersetzen) sollen:
Beispiel Armin (Antwort 1)
oder
Beispiel mapet (Antwort 2)
oder
Beispiel El Bobbele (Antwort 5)
Geht so eine Hilfestellung nicht verständlicher?
mfg Knubbel
ich bin kein Access-Profi und habe von VBA überhaupt keinen Schimmer (ich nutze meist die eingebauten Makro-Funktionen - Ich stehe hier im eingeschschränkten Widerspruch zu El Bobbele -)
Aber, bitte erklärt mir mal, wie Hilfesuchende solche Vorschläge verstehen (übersetzen) sollen:
Beispiel Armin (Antwort 1)
Zitat:
1. mit dem entwurfseditor für abfragen würde ich mir eine query zusammenstellen, die das tut was du willst problem: "ALLE Artikel zeigt, die entweder in Lager B oder C vorkommen,(oder beiden Lagern B+C) NICHT aber in Lager A.", hier im editor jede einzelne bedingung untereinander schreiben unter das feld "Lager").
damit hast du schon einmal den sql code für eine statische abfrage.
1. mit dem entwurfseditor für abfragen würde ich mir eine query zusammenstellen, die das tut was du willst problem: "ALLE Artikel zeigt, die entweder in Lager B oder C vorkommen,(oder beiden Lagern B+C) NICHT aber in Lager A.", hier im editor jede einzelne bedingung untereinander schreiben unter das feld "Lager").
damit hast du schon einmal den sql code für eine statische abfrage.
oder
Beispiel mapet (Antwort 2)
Zitat:
wobei vt eine verknüpfungstabelle n:m ist mit den jeweiligen Primärschlüsseln von Lager und Artikel
wobei vt eine verknüpfungstabelle n:m ist mit den jeweiligen Primärschlüsseln von Lager und Artikel
oder
Beispiel El Bobbele (Antwort 5)
Zitat:
Das kann mit einer Abfrage realisiert werden. Wenn du die Namen deiner betroffenen Tabelle und Felder nennst
Das kann mit einer Abfrage realisiert werden. Wenn du die Namen deiner betroffenen Tabelle und Felder nennst
Geht so eine Hilfestellung nicht verständlicher?
mfg Knubbel
Antwort 8 von Zeroo
Hi zusammen!
Hier wird ja fleißig diskutiert. Also El Bobbele ich habe bis jetzt noch gar keine Tabellen oder Abfragen und auch noch keine Namen vergeben, weil ich erst das bekannte Problem lösen wollte, bevor ich mich in die Materie stürze.
Großes Dankeschön für die vielen hilfreichen Antworten.
Wenn ich demnächst mal Zeit finde kann ich es ja mal auf die Art versuchen, wie du es geschildert hast Knubbel - es sei denn ElBobbele ist so frei und schickt mir die SQL Anweisung. Das wär natürlich das höchste aller Gefühle ;););)
Danke @all!
Gruuuß
Zeroo
Hier wird ja fleißig diskutiert. Also El Bobbele ich habe bis jetzt noch gar keine Tabellen oder Abfragen und auch noch keine Namen vergeben, weil ich erst das bekannte Problem lösen wollte, bevor ich mich in die Materie stürze.
Großes Dankeschön für die vielen hilfreichen Antworten.
Wenn ich demnächst mal Zeit finde kann ich es ja mal auf die Art versuchen, wie du es geschildert hast Knubbel - es sei denn ElBobbele ist so frei und schickt mir die SQL Anweisung. Das wär natürlich das höchste aller Gefühle ;););)
Danke @all!
Gruuuß
Zeroo
Antwort 9 von El Bobbele
Hallo Knubbel!
Also was mich betrifft, ich wollte mit einer ausführlicheren Erklärung warten, bis Zeroo mit seinen Namen rübergewachsen ist. Ich fand es besser, "seine" Lösung zu erklären, als eine fiktive, die er noch an seine Datenbank anpassen musste. Ausserdem wusste ich noch nicht, ob er tatsächlich nur eine Tabelle benutzt oder doch schon drei. Ich hätte demnach zwei Lösungen präsentieren müssen, wovon eine von vornherein für die Ablage P entwickelt worden wäre. :-)
Jetzt aber zu deinen Fragen:
1) Das zu beantworten bedeutet sehr viel Tipparbeit. Ich versuche das am Besten mit Beispielen zu erklären und verweise dann auf Texte im Internet, die das schon Zigtausendfach erklärt haben. Damit ist uns allen gedient, denke ich.
Ich verwende mal Zeroo's Buchstabenspiele und ersetze sie durch richtige Begriffe, das macht das Lesen einfacher:
Hier taucht jeder Begriff mehrmals auf. Das kostet unnötigen Speicherplatz und Tippfehler erzeugen mehrfach vorkommende Lagerorte oder Artikel. Solche (Excel-typischen) Tabellen sind völlig ungeeignet für relationale Datenbanken wie Access, in denen Daten in die Einzelteile zerlegt werden. Diese Zerlegung wird Normalisierung (Google, Donkarl 1.31) genannt, die Datenbank wird dabei in den "Normalzustand" gebracht.
Im aktuellen Beispiel müssten dazu für Lagerorte und Artikel jeweils eine Tabelle angelegt und jedes Element einmal dort eingetragen werden:
Irgendwann sollen die Artikel auch mal diversen Lagern zugeordnet werden. Dabei gilt:
- Ein Lager kann mehrere Artikel speichern
- Ein Artikel kann in mehreren Lagern vorhanden sein
Das ist eine klassische m:n-Beziehung. Und die wird üblicherweise über eine dritte Tabelle realisiert, welche zwei 1:n-Beziehungen zu den zwei vorangegangenen Tabellen pflegt und deren Primärschlüssel speichert. Wenn in München z.B. Schrauben verfügbar sind, dann sieht die Tabelle tblLagerArtikel so aus:
Und das wurde hier mit "3-Tabellenlösung" bezeichnet: tblLager, tblArtikel, tblLagerArtikel. Bis hierhin sollte der Normalisierungs-Crashkurs reichen. Die o.g. Links bieten ausreichend Literatur zur Vertiefung. Wer sich noch nicht mit der Datenbank-Normalisierung auseinandergesetzt hat, sollte das unbedingt tun!!! Das ist ein EXTREM wichtiges Thema, denn hier ist das Fundament einer Datenbank betroffen und eine Datenbank steht und fällt mit ihrem Fundament!!!!
Weiter mit Frage 2:
Aufgabenstellung: Ich möchte alle Artikel aus allen Lagern haben, die nicht in München vorhanden sind. Dazu werden zwei Abfragen benötigt. Die erste kann beschrieben werden mit "Gib alle Primärschlüssel der LagerArtikel-Tabelle zurück, deren Artikel zum Lager München gehören:
Diese Abfrage wird in eine neue Abfrage aufgenommen, die erstmal nur alle Lager und Artikel zurückgibt:
Hier wird die erste Abfrage eingefügt mit einer OUTER JOIN-Beziehung (LEFT/RIGHT JOIN), d.h. die Abfrage gibt alle Daten aus der zweiten Abfrage zurück und nur die Datensätze aus der ersten, die auch in der ersten Abfrage selbst vorhanden sind. Wenn im Lager München demnach Artikel nicht vorhanden sind, dann ist der Rückgabewert aus der ersten Abfrage zwangsweise NULL. Danach wird gefiltert und damit ist die Abfrage auch schon fertig:
Die erste Abfrage ist in meinem Beispiel komplett als temporäre Abfrage in der eckigen Klammer enthalten. Hier könnte genausogut der Name einer abgespeicherten Abfrage stehen.
Die drei Tabellen lassen sich auch sehr gut als Formular darstellen. tblLager ist ein Hauptformular in Einzelformularansicht, tblLagerArtikel das Unterformular in Endlosformularansicht. Beide Formulare sind über LAG_ID und LA_LAG_ID verknüpft. Die Artikel werden per Kombinationsfeld bereitgestellt, welches an LA_ART_ID gebunden ist. Am Ende können die Lager seitenweise durchgeklickt werden und die Artikel per Kombobox in einem Endlosformular ausgewählt werden. Wenn man die Sache dann ausbaut, dann könnte in tblLagerArtikel auch noch eine Menge-Spalte eingefügt werden usw.
Das war es dann erstmal von meiner Seite. Fehlt nur noch ein dickes Lob für Knubbel, weil er die Bremse gezogen hat, wenn Erklärungen nicht verständlich sind. Das Nachhaken mit Nacharbeit ist mir persönlich tausendmal lieber, als Lösungsansätze kommentarlos unter den Tisch fallen zu lassen, nur weil sie auf Anhieb nicht verstanden werden. *daumenhoch* :-)
Gruss
El Bobbele
Also was mich betrifft, ich wollte mit einer ausführlicheren Erklärung warten, bis Zeroo mit seinen Namen rübergewachsen ist. Ich fand es besser, "seine" Lösung zu erklären, als eine fiktive, die er noch an seine Datenbank anpassen musste. Ausserdem wusste ich noch nicht, ob er tatsächlich nur eine Tabelle benutzt oder doch schon drei. Ich hätte demnach zwei Lösungen präsentieren müssen, wovon eine von vornherein für die Ablage P entwickelt worden wäre. :-)
Jetzt aber zu deinen Fragen:
1) Das zu beantworten bedeutet sehr viel Tipparbeit. Ich versuche das am Besten mit Beispielen zu erklären und verweise dann auf Texte im Internet, die das schon Zigtausendfach erklärt haben. Damit ist uns allen gedient, denke ich.
Ich verwende mal Zeroo's Buchstabenspiele und ersetze sie durch richtige Begriffe, das macht das Lesen einfacher:
Lagerort Artikel
Berlin Schraube
München Schraube
Berlin Mutter
Frankfurt Mutter
München Dübel
Frankfurt Dübel
Berlin Nagel
München Nagel
Frankfurt NagelHier taucht jeder Begriff mehrmals auf. Das kostet unnötigen Speicherplatz und Tippfehler erzeugen mehrfach vorkommende Lagerorte oder Artikel. Solche (Excel-typischen) Tabellen sind völlig ungeeignet für relationale Datenbanken wie Access, in denen Daten in die Einzelteile zerlegt werden. Diese Zerlegung wird Normalisierung (Google, Donkarl 1.31) genannt, die Datenbank wird dabei in den "Normalzustand" gebracht.
Im aktuellen Beispiel müssten dazu für Lagerorte und Artikel jeweils eine Tabelle angelegt und jedes Element einmal dort eingetragen werden:
tblLager tblArtikel
LAG_ID LAG_Name ART_ID ART_Name
1 Berlin 1 Schraube
2 Frankfurt 2 Mutter
3 München 3 Dübel
4 NagelIrgendwann sollen die Artikel auch mal diversen Lagern zugeordnet werden. Dabei gilt:
- Ein Lager kann mehrere Artikel speichern
- Ein Artikel kann in mehreren Lagern vorhanden sein
Das ist eine klassische m:n-Beziehung. Und die wird üblicherweise über eine dritte Tabelle realisiert, welche zwei 1:n-Beziehungen zu den zwei vorangegangenen Tabellen pflegt und deren Primärschlüssel speichert. Wenn in München z.B. Schrauben verfügbar sind, dann sieht die Tabelle tblLagerArtikel so aus:
LA_ID LA_LAG_ID LA_ART_ID
1 3 1Und das wurde hier mit "3-Tabellenlösung" bezeichnet: tblLager, tblArtikel, tblLagerArtikel. Bis hierhin sollte der Normalisierungs-Crashkurs reichen. Die o.g. Links bieten ausreichend Literatur zur Vertiefung. Wer sich noch nicht mit der Datenbank-Normalisierung auseinandergesetzt hat, sollte das unbedingt tun!!! Das ist ein EXTREM wichtiges Thema, denn hier ist das Fundament einer Datenbank betroffen und eine Datenbank steht und fällt mit ihrem Fundament!!!!
Weiter mit Frage 2:
Aufgabenstellung: Ich möchte alle Artikel aus allen Lagern haben, die nicht in München vorhanden sind. Dazu werden zwei Abfragen benötigt. Die erste kann beschrieben werden mit "Gib alle Primärschlüssel der LagerArtikel-Tabelle zurück, deren Artikel zum Lager München gehören:
SELECT tblLagerArtikel.LA_ID
FROM tblLagerArtikel INNER JOIN tblLager
ON tblLagerArtikel.LA_ART_ID = tblLager.ART_ID
WHERE tblLager.LAG_Name = "München";Diese Abfrage wird in eine neue Abfrage aufgenommen, die erstmal nur alle Lager und Artikel zurückgibt:
SELECT tblLager.LAG_Name, tblArtikel.ART_Name
FROM tblLager INNER JOIN
(tblArtikel INNER JOIN tblLagerArtikel
ON tblArtikel.ART_ID = tblLagerArtikel.LA_ART_ID)
ON tblLager.LAG_ID = tblLagerArtikel.LA_LAG_ID;Hier wird die erste Abfrage eingefügt mit einer OUTER JOIN-Beziehung (LEFT/RIGHT JOIN), d.h. die Abfrage gibt alle Daten aus der zweiten Abfrage zurück und nur die Datensätze aus der ersten, die auch in der ersten Abfrage selbst vorhanden sind. Wenn im Lager München demnach Artikel nicht vorhanden sind, dann ist der Rückgabewert aus der ersten Abfrage zwangsweise NULL. Danach wird gefiltert und damit ist die Abfrage auch schon fertig:
SELECT tblLager.LAG_Name, tblArtikel.ART_Name
FROM [SELECT tblLagerArtikel.LGA_ART_ID
FROM tblLager INNER JOIN tblLagerArtikel
ON tblLager.LAG_ID = tblLagerArtikel.LA_LAG_ID
WHERE ((tblLager.LAG_Name)="München")]. AS Temp
RIGHT JOIN (tblLager INNER JOIN (tblArtikel INNER JOIN tblLagerArtikel
ON tblArtikel.ART_ID = tblLagerArtikel.LA_ART_ID)
ON tblLager.LAG_ID = tblLagerArtikel.LA_LAG_ID)
ON Temp.LA_ART_ID = tblLagerArtikel.LA_ART_ID
WHERE ((Temp.LA_ART_ID) Is Null);Die erste Abfrage ist in meinem Beispiel komplett als temporäre Abfrage in der eckigen Klammer enthalten. Hier könnte genausogut der Name einer abgespeicherten Abfrage stehen.
Die drei Tabellen lassen sich auch sehr gut als Formular darstellen. tblLager ist ein Hauptformular in Einzelformularansicht, tblLagerArtikel das Unterformular in Endlosformularansicht. Beide Formulare sind über LAG_ID und LA_LAG_ID verknüpft. Die Artikel werden per Kombinationsfeld bereitgestellt, welches an LA_ART_ID gebunden ist. Am Ende können die Lager seitenweise durchgeklickt werden und die Artikel per Kombobox in einem Endlosformular ausgewählt werden. Wenn man die Sache dann ausbaut, dann könnte in tblLagerArtikel auch noch eine Menge-Spalte eingefügt werden usw.
Das war es dann erstmal von meiner Seite. Fehlt nur noch ein dickes Lob für Knubbel, weil er die Bremse gezogen hat, wenn Erklärungen nicht verständlich sind. Das Nachhaken mit Nacharbeit ist mir persönlich tausendmal lieber, als Lösungsansätze kommentarlos unter den Tisch fallen zu lassen, nur weil sie auf Anhieb nicht verstanden werden. *daumenhoch* :-)
Gruss
El Bobbele
Antwort 10 von Knubbel
Hi El Bobbele,
vorerst einmal Dank für deinen ausführlichen Beitrag.
Ich habe leider z.Z. wenig Möglichkeit mich detailiert hiermit zu beschäftigen.
Schätzungsweise in 2-3 Tagen werde ich mich melden.
mmfg Knubbel
vorerst einmal Dank für deinen ausführlichen Beitrag.
Ich habe leider z.Z. wenig Möglichkeit mich detailiert hiermit zu beschäftigen.
Schätzungsweise in 2-3 Tagen werde ich mich melden.
mmfg Knubbel
Antwort 11 von Zeroo
Hi El Bobbele!
Mal ein großes Dankeschön für deine ganze Arbeit! Hab mich riesig gefreut und meine Datenbank läuft auch schon so wie ichs will! Daaaaanke!!!!
Für alle die auch so eine Datenbank wollen: Ich den oberen Abfragen sind ein paar kleine Tippfehler enthalten: Richtig sind sie so:
Abfrage 1:
SELECT tblLagerArtikel.LA_ID
FROM tblLagerArtikel INNER JOIN tblLager ON tblLagerArtikel.LA_LAG_ID=tblLager.LAG_ID
WHERE tblLager.LAG_Name="München";
Abfrage 3:
SELECT tblLager.LAG_Name, tblArtikel.ART_Name
FROM [SELECT tblLagerArtikel.LA_ART_ID
FROM tblLager INNER JOIN tblLagerArtikel
ON tblLager.LAG_ID = tblLagerArtikel.LA_LAG_ID
WHERE ((tblLager.LAG_Name)="München")]. AS Temp RIGHT JOIN (tblLager INNER JOIN (tblArtikel INNER JOIN tblLagerArtikel ON tblArtikel.ART_ID = tblLagerArtikel.LA_ART_ID) ON tblLager.LAG_ID = tblLagerArtikel.LA_LAG_ID) ON Temp.LA_ART_ID = tblLagerArtikel.LA_ART_ID
WHERE ((Temp.LA_ART_ID) Is Null);
Grüße an Alle
Zeroo
Mal ein großes Dankeschön für deine ganze Arbeit! Hab mich riesig gefreut und meine Datenbank läuft auch schon so wie ichs will! Daaaaanke!!!!
Für alle die auch so eine Datenbank wollen: Ich den oberen Abfragen sind ein paar kleine Tippfehler enthalten: Richtig sind sie so:
Abfrage 1:
SELECT tblLagerArtikel.LA_ID
FROM tblLagerArtikel INNER JOIN tblLager ON tblLagerArtikel.LA_LAG_ID=tblLager.LAG_ID
WHERE tblLager.LAG_Name="München";
Abfrage 3:
SELECT tblLager.LAG_Name, tblArtikel.ART_Name
FROM [SELECT tblLagerArtikel.LA_ART_ID
FROM tblLager INNER JOIN tblLagerArtikel
ON tblLager.LAG_ID = tblLagerArtikel.LA_LAG_ID
WHERE ((tblLager.LAG_Name)="München")]. AS Temp RIGHT JOIN (tblLager INNER JOIN (tblArtikel INNER JOIN tblLagerArtikel ON tblArtikel.ART_ID = tblLagerArtikel.LA_ART_ID) ON tblLager.LAG_ID = tblLagerArtikel.LA_LAG_ID) ON Temp.LA_ART_ID = tblLagerArtikel.LA_ART_ID
WHERE ((Temp.LA_ART_ID) Is Null);
Grüße an Alle
Zeroo
Antwort 12 von Zeroo
Hellou ägäään! *sing*
Nächste Problem ... ach es reißt nicht ab ;) *zwinker*
Meine so erstellte Datenbank funktioniert jetzt nur wenn alle Felddatentypen übereinstimmen, also müssen folgende Felder gleich sein:
tblLager.LAG_ID
tblArtikel.ART_ID
tblLagerArtikel.LA_LAG_ID
tblLagerArtikel.LA_ART_ID
Da ich aber in die Tabelle "tblLagerArtikel" und somit in die Felder
tblLagerArtikel.LA_LAG_ID
tblLagerArtikel.LA_ART_ID
eintragen möchte wo ich was einlagere (also Text als Datentyp) kann ich die Felder
tblLager.LAG_ID
tblArtikel.ART_ID
nicht auf (AutoWert) setzen.
Sonst kommt die Fehlermeldung
"Im Ausdruck stimmt ein Datentyp nicht überein"
Ich möchte aber nicht jedesmal von Hand eine ID eingeben wenn ich einen neuen Artikel hinzufüge.
...wie löse ich das Problem?
Grüßies
Zeroo
Nächste Problem ... ach es reißt nicht ab ;) *zwinker*
Meine so erstellte Datenbank funktioniert jetzt nur wenn alle Felddatentypen übereinstimmen, also müssen folgende Felder gleich sein:
tblLager.LAG_ID
tblArtikel.ART_ID
tblLagerArtikel.LA_LAG_ID
tblLagerArtikel.LA_ART_ID
Da ich aber in die Tabelle "tblLagerArtikel" und somit in die Felder
tblLagerArtikel.LA_LAG_ID
tblLagerArtikel.LA_ART_ID
eintragen möchte wo ich was einlagere (also Text als Datentyp) kann ich die Felder
tblLager.LAG_ID
tblArtikel.ART_ID
nicht auf (AutoWert) setzen.
Sonst kommt die Fehlermeldung
"Im Ausdruck stimmt ein Datentyp nicht überein"
Ich möchte aber nicht jedesmal von Hand eine ID eingeben wenn ich einen neuen Artikel hinzufüge.
...wie löse ich das Problem?
Grüßies
Zeroo
Antwort 13 von El Bobbele
Hallo Zeroo!
Den ersten Fehler konnte ich eben noch ausfindig machen, anstelle LAG_ID schrieb ich ART_ID in der ersten Abfrage. Aber wo ist der Fehler in der zweiten Abfrage?
Alle Felder, die nur ein Buchstabenkürzel vor _ID stehen haben (LA_ID, ART_ID, LAG_ID), sind Autowerte. Die zwei zusätzlichen Felder in tblLagerArtikel sind vom Zahlen-Datentyp Long. Weiterhin sollte in allen _ID-Feldern die Standardwert-Eigenschaft gelöscht werden. Du darfst dazu die Beziehungen zwischen den drei Tabellen nicht vergessen:
tblLager.LAG_ID -> tblLagerArtikel.LA_LAG_ID
tblArtikel.ART_ID -> tblLagerArtikel.LA_ART_ID
In die Tabelle LagerArtikel dürfen nur Zahlen eingetragen werden. Die Artikel- und Lagertexte müssen in die Tabelle tblArtikel und tblLager. Für den Zweck habe ich in meinem Beispiel die Felder ART_Name und LAG_Name vorgesehen. Die direkte Tabellenpflege ist natürlich so nicht sonderlich einfach, deswegen solltest du dir noch ein Formular dazu basteln, wie ich es am Ende von Antwort 9 grob beschrieben habe. Melde dich nochmal, wenn es da irgendwo hakt.
Nochmal zusammengefasst: Nur in den Tabellen tblLager und tblArtikel existieren die jeweiligen Texte. Die dritte Tabelle tblLagerArtikel bildet die Paarungen zwischen den ersten beiden Tabellen. Über die Beziehungen weiss Access dann, welche Lager-Texte mit welchen Artikel-Texten verbunden werden müssen.
Gruss
El Bobbele
Den ersten Fehler konnte ich eben noch ausfindig machen, anstelle LAG_ID schrieb ich ART_ID in der ersten Abfrage. Aber wo ist der Fehler in der zweiten Abfrage?
Alle Felder, die nur ein Buchstabenkürzel vor _ID stehen haben (LA_ID, ART_ID, LAG_ID), sind Autowerte. Die zwei zusätzlichen Felder in tblLagerArtikel sind vom Zahlen-Datentyp Long. Weiterhin sollte in allen _ID-Feldern die Standardwert-Eigenschaft gelöscht werden. Du darfst dazu die Beziehungen zwischen den drei Tabellen nicht vergessen:
tblLager.LAG_ID -> tblLagerArtikel.LA_LAG_ID
tblArtikel.ART_ID -> tblLagerArtikel.LA_ART_ID
In die Tabelle LagerArtikel dürfen nur Zahlen eingetragen werden. Die Artikel- und Lagertexte müssen in die Tabelle tblArtikel und tblLager. Für den Zweck habe ich in meinem Beispiel die Felder ART_Name und LAG_Name vorgesehen. Die direkte Tabellenpflege ist natürlich so nicht sonderlich einfach, deswegen solltest du dir noch ein Formular dazu basteln, wie ich es am Ende von Antwort 9 grob beschrieben habe. Melde dich nochmal, wenn es da irgendwo hakt.
Nochmal zusammengefasst: Nur in den Tabellen tblLager und tblArtikel existieren die jeweiligen Texte. Die dritte Tabelle tblLagerArtikel bildet die Paarungen zwischen den ersten beiden Tabellen. Über die Beziehungen weiss Access dann, welche Lager-Texte mit welchen Artikel-Texten verbunden werden müssen.
Gruss
El Bobbele
Antwort 14 von Zeroo
Hi El Bobbele!
War nur ein Buchstabendreher. Statt LAG_ART_ID hast du LGA_ART_ID geschrieben.
Meinst du du kannst mir deine funktionierende Datenbank mal mailen? Du würdest in meinen persönlichen Access-Helden-Olymp kommen! ;)
Viele Grüße an Alle, die die Nerven haben meine Posts zu lesen ;) ;) ;)
bye
Zeroo
War nur ein Buchstabendreher. Statt LAG_ART_ID hast du LGA_ART_ID geschrieben.
Meinst du du kannst mir deine funktionierende Datenbank mal mailen? Du würdest in meinen persönlichen Access-Helden-Olymp kommen! ;)
Viele Grüße an Alle, die die Nerven haben meine Posts zu lesen ;) ;) ;)
bye
Zeroo
Antwort 15 von El Bobbele
Hallo Zeroo!
Ich habe diesbezüglich keine Datenbank, die Tabellendefinitionen sind frei erfunden und die SQL-Anweisungen sind händisch getippt. Was meinst du, woher denn die Tippfehler kommen? ;-)
Gruss
El Bobbele
Ich habe diesbezüglich keine Datenbank, die Tabellendefinitionen sind frei erfunden und die SQL-Anweisungen sind händisch getippt. Was meinst du, woher denn die Tippfehler kommen? ;-)
Gruss
El Bobbele
Antwort 16 von Zeroo
*smile* ... alles klar! THX anyway... Den Platz in meinem Access Olymp hast du sicher :)
Antwort 17 von El Bobbele
Du solltest besser das Supportnet allgemein in deinen Olymp hieven. Ich bin ja nicht der einzige Helfer hier und andere haben hier im Access-Bereich weit mehr geleistet als ich. :-)

