September 24, 2020, 05:01:48

Neuigkeiten:

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


Mehrere Kriterien in einer Spalte

Begonnen von pmmuc, September 10, 2020, 20:54:49

⏪ vorheriges - nächstes ⏩

pmmuc

Hallo Zusammen,
ich habe 2 Tabellen (tblNamen und tblEvent) die über eine 3. Tabelle (tblNameEvent) zu einer m:n Verbindung verbunden sind. Wenn ich nun wissen will welcher Name bei welchen Event mit dabei war, so funktioniert das wunderbar.
WHERE tblEvent.Eventbezeichnung = '" & Filter1 & "'Filter1 ist eine Event z.B. Kino.
Wenn ich aber nun wissen will welcher Name bei Event1 UND Event2 ( UND Event3 ....) mit dabei war und die Filterbedingungen über eine AND Verknüpfung verbinde, so bekomme ich immer nur eine leere Tabelle.
Kann mir jemand einen Tipp geben wie ich hier weiterkomme.
Gruß
Peter

ShenTo19

Hallo,
Du darfst die Events nicht mit "und" verknüpfen sondern mit "oder", sonst wird die Bedingung nur erfüllt, wenn der Name bei allen im Filter vorkommenden Events anwesend war. Es könnte je jemand nur bei Event 1 + 3 (oder anderen Kombinationen) gewesen sein.
Gruß Thomas


pmmuc

schon mal danke für die schnellen Antworten.
Es muss schon eine UND Verknüpfung sein.

Beispiel: (Filtern nach Event1 UND Event2 UND Event3)
Name1 hat teilgenommen an Event1 UND Event2 UND Event3 --> Treffer
Name2 hat teilgenommen an Event1 UND Event3 (aber nicht an Event2) --> kein Treffer.

Bei einer ODER Verknüpfung würde auch Name2 einen Treffer erzielen und das sollte nicht sein.

Gruß Peter

DF6GL

September 11, 2020, 09:15:29 #4 Letzte Bearbeitung: September 11, 2020, 09:35:44 von DF6GL
Hallo,

zeig mal den Screenshot des Beziehungsfensters (alle Tabellenfelder sichtbar)...

Ansonsten:

Select NachName, Count(Event) AS AnzahlvonEvent
From tblNameEvent
Where Event in ("Kino","Oper","Festival")
Group by NachName
Having Count(Event)=3

ebs17

September 11, 2020, 09:35:21 #5 Letzte Bearbeitung: September 11, 2020, 09:48:55 von ebs17
Ein Feld in einer Spalte enthält (geplant und sinnvollerweise) nur einen Inhalt. Daher kann man nicht direkt auf mehrere Inhalte per AND-Verknüpfung prüfen.

Daher wird man eine OR-Verknüpfung mit einem Zählen verknüpfen. Beipiel auf die Verknüpfungstabelle reduziert:
SELECT
   Name_ID
FROM
   tblNameEvent
WHERE
   Event_ID IN (2, 3, 5, 8)
GROUP BY
   Name_ID
HAVING
   COUNT(*) = 4
Die Anzahl der Elemente in der IN-Klausel muss mit dem Zählen korrespondieren, dabei sollten selbstredend die Kombinationen aus Name und Event eindeutig sein oder vorher eindeutig gestellt werden.

Über einen einfachen Filter oder Parameterübergabe ist das nicht mehr umzusetzen. Man müsste schon die SQL-Anweisung dynamisch zusammensetzen, oder man verwendet alternativ eine zusätzliche Parametertabelle. Im zweiten Fall bleibt die SQL-Anweisung statisch, und die Dynamik erfolgt über Schreiben und Lesen in der Parametertabelle.
SELECT
   Name_ID
FROM
   tblNameEvent
WHERE
   Event_ID IN
      (SELECT MyValue FROM tblParameter)
GROUP BY
   Name_ID
HAVING
   COUNT(*) =
      (SELECT COUNT(*) FROM tblParameter)
Diese Abfrage kann nun mit der Namenstabelle verknüpft werden, um die Klarnamen zu bekommen. Die Auswahl der Events dürfte praktisch sowieso per VBA erfolgen, da wird man also gleich nur die IDs übergeben.
Mit freundlichem Glück Auf!

Eberhard

pmmuc

Hallo Zusammen,
vielen Dank für die Anregungen. Mit IN und HAVING habe ich bislang noch nicht gearbeitet, werde mich aber gleich damit beschäftigen und versuchen die Vorschläge umzusetzen.
Sobald ich Ergebnisse habe gebe ich natürlich Rückmeldung.
DF6GL: hier noch meine Beziehungen
Sie dürfen in diesem Board keine Dateianhänge sehen.

Gruß Peter

PhilS

Ich wollte eigentlich schreiben, dass die bisherigen Vorschläge noch nicht zum Ziel führen und man explizit für jedes Event auf die Existenz eines entsprechenden Datensatzes in tblNameEvent prüfen muss. Etwa so:
SELECT ne1.NamenIdRef
FROM tblNameEvent ne1
WHERE ne1.EventIdRef = 1
AND EXISTS (SELECT 'x'
FROM tblNameEvent ne2
WHERE ne2.NamenIdRef = ne1.NamenIdRef
AND ne2.EventIdRef = 2
)
AND EXISTS (SELECT 'x'
FROM tblNameEvent ne3
WHERE ne3.NamenIdRef = ne1.NamenIdRef
AND ne3.EventIdRef = 3
)

Bei genauerem Hinschauen muss ich anerkennen, dass die Lösung von @ebs17 richtig clever ist und durch das Eliminieren der Duplikate beim Zählen sogar auch dann funktioniert, wenn es Mehrfachzuordnungen von einem Event zu einem Namen gibt.
In Verbindung mit der Parametertabelle ist die Lösung von ebs17 deutlich einfacher zu handhaben.
Access DevTools - Find and Replace
Komfortables Suchen und Ersetzen in den Entwurfseigenschaften von Access-Objekten. In Abfragen, Formularen, Berichten und VBA-Code - Überall und rasend schnell!

ebs17

Dank an Philipp: Es ist immer wieder gut, verschiedene Formulierungen von Abfragen zu sehen und überhaupt daran zu denken, dass es sie gibt und man sie prüfen kann.

Solche wie von Dir gezeigten EXISTS-Reihen hatte ich mal im Einsatz, als eine Aufgabenstellung etwa so lautete: Finde die Namen, die an allen Events 1+3+4, nicht jedoch bei Events 2+5 teilgenommen haben. Oder auch Teilnahme an 1+4+7, aber nicht an 2+8 usw. in der Verkettung.
Eine solche Anweisung hatte dann mit realen Bedingungen eine Textlänge von etwa 1.300 Zeichen (bei sparsamer Klammerung und Kurz-Tabellenaliasen)), immerhin noch weit weg von möglichen 64.000.
So etwas schreibt man dann aber nicht mehr per Hand, sondern per VBA mit Textbausteinen in Schleife mit Ersetzungen von Platzhaltern.
Mit freundlichem Glück Auf!

Eberhard

pmmuc

Hallo,
nach langem Probieren bin ich zu der Erkenntnis gekommen, dass ich noch weitere Hilfe benötige.
Ich habe nun folgenden Code:
SQL = "SELECT tblNameEvent.NamenIDRef, tblNameEvent.EventIDRef, tblNameEvent.NamEventID" & _
" FROM tblNameEvent" & _
" WHERE EventIDRef IN(SELECT EventFilter FROM tblParameter)" & _
" GROUP BY tblNameEvent.NamenIDRef, tblNameEvent.EventIDRef, tblNameEvent.NamEventID" & _
" HAVING COUNT(*) = (SELECT COUNT(*) FROM tblParameter)"
   
Me.lstGefiltert2.RowSource = SQL
Bis zur Zeile Group By ... funktioniert alles Erwartungsgenäß.
Sobald ich aber die Zeile Having Count(*) ... hinzufüge, bekomme ich immer eine leere Liste.
Wo liegt mein Fehler?

Gruß Peter

ebs17

In meinem Vorschlag steht sehr bewusst und absichtlich nur eine ID im SELECT- sowie im GROUP BY-Abschnitt. Jede Abweichung davon setzt eine andere Logik um und wird ein anderes Ergebnis als nachgefragt bringen.
Warum bringst Du da eigene "Kreativität" ein?

Ein Gruppieren über den Primärschlüssel ist dann zusätzlich sinnfrei, da dieser definiert eindeutig ist und somit nicht in gleiche Gruppen zusammenfassbar ist.
Mit freundlichem Glück Auf!

Eberhard

pmmuc

Danke für den Hinweis.
Es ist wohl weniger eigene Kreativität als mehr eigenes Unwissen.
Ich habe nun den Code geändert in
SQL = "SELECT tblNameEvent.NamenIDRef" & _
" FROM tblNameEvent" & _
" WHERE EventIDRef IN(SELECT EventFilter FROM tblParameter)" & _
" GROUP BY tblNameEvent.NamenIDRef" & _
" HAVING COUNT(*) = (SELECT COUNT(*) FROM tblParameter)"
   
Me.lstGefiltert2.RowSource = SQL
Ich bekomme nun ein Ergebnis, es muss aber noch ein Fehler vorhanden sein, denn das Ergebnis ist leider falsch.
In meinem Beispiel habe ich in der Parametertabelle zwei Events stehen, bekomme aber in der Ergebnisliste auch Namen angezeigt die nur an einem Event teilgenommen haben.
Ich hoffe auf nochmalige Hilfe.
Gruß Peter

ebs17

ZitatSELECT EventFilter FROM tblParameter
Aus diesem Teil der Anweisung sollte klar genug hervorgehen, dass die Parametertabelle genau ein Feld hat und die eingetragenen Werte Datensätze bilden.
Mit freundlichem Glück Auf!

Eberhard

PhilS

Muss nicht die EventId ebenfalls in der Liste der Ausgabespalten sein, um über die Gruppierung die korrekte Anzahl zu erhalten?
Access DevTools - Find and Replace
Komfortables Suchen und Ersetzen in den Entwurfseigenschaften von Access-Objekten. In Abfragen, Formularen, Berichten und VBA-Code - Überall und rasend schnell!

pmmuc

Vielen Dank für die Hilfe, aber jetzt bin ich komplett abgehängt.
Meine Parametertabelle sieht wie folgt aus:
Sie dürfen in diesem Board keine Dateianhänge sehen.
Die Spalte EventFilter ist LongInteger und ich trage hier die Events (ID) ein, nach denen gefilter werden soll. Jedes Event eine neue Zeile. Muss ich hier etwas anders machen?

Wie soll ich denn nun meinen Code verändern.
Bitte habt Verständnis ich bin Access-Anfänger und verstehe evtl. manches falsch.
Gruß Peter