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?
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.
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
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.
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.
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]
… 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]
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…
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.
INTERSECT heißt das Schlüsselwort, also z. B.
SELECT a FROM tab WHERE b=5
INTERSECT
SELECT a FROM tab WHERE b=7