SQL: Kriterium über mehrere Tupel

Hallo Leute,

habe eine Zuordnungstabelle, die eine m:n-Verknüpfung simuliert

A | B

1 | 5
1 | 6
2 | 5
2 | 7
3 | 6
3 | 7
1 | 8
2 | 8

Primärschlüssel zusammengesetzt aus A und B

Gesucht sind alle A, die mindestens ganz bestimmen B (z.B. 5 und 8) zugeordnet sind.
Mein Programm soll eine SQL-Anweisung generieren, die die gesuchten A liefert. Das Programm soll mit einer umbestimmten Menge von Kriterien (z.B. „5“ und „8“) gefüttert werden und die entsprechende SQL-Anweisung erzeugen.

Das Programm ist nicht das Problem. Aber wie kann die SQL-Anweisung aussehen?

Vorab vielen Dank!
Jochen

TEILWEISE Lösung als View
Zwischenergebnis:
Habe ein TEILWEISES Ergebnis:

CREATE VIEW temp AS
SELECT A, 5
FROM tab
WHERE A=5
UNION
SELECT A, 8
FROM tab
WHERE A=8
;
SELECT A
FROM temp
GROUP BY A
HAVING COUNT(*)=2

Problem hierbei ist, daß temp je nach Kriterien und Anzahl der Kriterien (hier: 5 und 8) dynamisch erzeugt werden muß, und zwar im Netzwerk von verschiedenen Stellen aus unabhängig. Da die VIEW aber meines Wissens in der DB abgelegt wird, kann ich diese Lösung nicht verwenden.

Hat jemand eine Idee, wie man evtl. eine „lokale temporäre VIEW“ oder etwas ähnliches erzeugen kann? Dann wäre das Problem nämlich gelöst.

Vorab schonmal vielen Dank!
Jochen

Das Programm ist nicht das Problem. Aber
wie kann die SQL-Anweisung aussehen?

SELECT a,b FROM tab WHERE b=5 OR b=6 OR b=7

Die ORs kannst du beliebig oft dynamisch einhängen.

Grüße, Robert

Hallo Leute,

habe eine Zuordnungstabelle, die eine
m:n-Verknüpfung simuliert

A | B

1 | 5
1 | 6
2 | 5
2 | 7
3 | 6
3 | 7
1 | 8
2 | 8

Primärschlüssel zusammengesetzt aus A und
B

Gesucht sind alle A, die mindestens ganz
bestimmen B (z.B. 5 und 8) zugeordnet
sind.
Mein Programm soll eine SQL-Anweisung
generieren, die die gesuchten A liefert.
Das Programm soll mit einer umbestimmten
Menge von Kriterien (z.B. „5“ und „8“)
gefüttert werden und die entsprechende
SQL-Anweisung erzeugen.

Das Programm ist nicht das Problem. Aber
wie kann die SQL-Anweisung aussehen?

Wenn Du die SELECT-Anweisung dynamisch (zur Laufzeit) erzeugen kannst, kannst Du einfach einen n-fachen self-join machen (n = Anzahl der „B-Kriterien“):

select t1.a
from tab t1, tab t2
where t1.a = t2.a and
t1.b = 5 and
t2.b = 8

mit 3 „B-Kriterien“ (3, 6, 8):

select t1.a
from tab t1, tab t2, tab t3
where t1.a = t2.a and
t2.a = t3.a and
t1.b = 3 and
t2.b = 6 and
t3.b = 8

Elmar

geht nicht
Vielen Dank für Deine Mühe!

Leider ist die Anforderung, daß ich nur jene A brauche, die ALLE B-Kriterien erfüllen (also nicht OR sondern quasi AND). Da aber keine einzelne Zeile mehrere Kriterien im selben Feld erfüllen kann, muß das Kriterium über mehrere Zeilen definiert sein.

Dein Lösungsvorschlag bringt alle A, die mindestens ein Kriterium erfüllen.

Inzwischen habe ich auch eine Antwort erhalten, die tatsächlich eine Lösung bietet (siehe weiter oben). Allerdings erwarte ich dabei Performanceprobleme.

Gruß Jochen

geht, aber Optimierung nötig (Dringend)

Wenn Du die SELECT-Anweisung dynamisch
(zur Laufzeit) erzeugen kannst, kannst Du
einfach einen n-fachen self-join machen
(n = Anzahl der „B-Kriterien“):

select t1.a
from tab t1, tab t2
where t1.a = t2.a and
t1.b = 5 and
t2.b = 8

mit 3 „B-Kriterien“ (3, 6, 8):

select t1.a
from tab t1, tab t2, tab t3
where t1.a = t2.a and
t2.a = t3.a and
t1.b = 3 and
t2.b = 6 and
t3.b = 8

Elmar

Vielen Dank! Das müßte theoretisch funktionieren.

Allerdings erwarte ich große Performance-Probleme. Der n-fache Join bewirkt, daß bei m Datensätzen die Tabelle ca. „m-hoch-n“-fach durchlaufen wird. Das n im Exponenten macht die Sache unkalkulierbar langsam.

Hat noch jemand eine Idee zur Optimierung?

Ich muß das Ding schnell (sowohl vom Termin als auch von der Performance) zum Laufen bringen.

Gruß
Jochen

nur als theoretischer Ansatz brauchbar
Weil dies Software auf einer Runtime-Umgebung laufen soll, die kein CREATE unterstützt, ist CREATE VIEW ohnehin nicht möglich.

Meine Hoffnung setze ich momentan auf irgendeine Möglichkeit, lokal so etwas wire eine temporäre VIEW zu erzeugen.
… oder auf eine gute Idee von Euch…

Gruß
Jochen

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Na, nimm doch einfach das SELECT für die View und setze als Subquery ein:

SELECT A
FROM (
SELECT A, 5
FROM tab
WHERE A=5
UNION
SELECT A, 8
FROM tab
WHERE A=8
)
GROUP BY A
HAVING COUNT(*)=2

Die Subquery musst Du halt dynamisch generieren.

Elmar

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Dein Lösungsvorschlag bringt alle A, die
mindestens ein Kriterium erfüllen.

Sorry, habe ich falsch verstanden. :smile:

Grüße, Robert

Das habe ich schon probiert.

… FROM ( SELECT …
wird von der Engine nicht verarbeitet (Sybase SQL Anywhere).
Ist das in Standard-SQL überhaupt definiert?
… oder mache ich nur etwas falsch und es müßte genau so gehen?

Gruß
Jochen

[Bei dieser Antwort wurde das Vollzitat nachträglich automatisiert entfernt]

Schnittmenge?
Denkansatz aus anderer Richtung:

Gibt es ein Gegenteil von UNION?

So, wie UNION eine Vereinigungsmenge erzeugt, könnte es sein, daß es eine SQL-Operation gibt, die eine Schnittmenge erzeugt. Damit wäre mir wahrscheinlich geholfen.

Ich weiß zwar noch nicht, wie ich es dann genau realisieren könnte, aber vielleicht kommen wir der Sache so näher…

Wäre schön…

Gruß
Jochen

So, wie UNION eine Vereinigungsmenge
erzeugt, könnte es sein, daß es eine
SQL-Operation gibt, die eine Schnittmenge
erzeugt. Damit wäre mir wahrscheinlich
geholfen.

Jo, jetzt wo du es sagst. :smile:

INTERSECT heißt das Schlüsselwort, also z. B.

SELECT a FROM tab WHERE b=5
INTERSECT
SELECT a FROM tab WHERE b=7

Grüße, Robert