dedlfix: wheri in all

Beitrag lesen

Tach!

Das ist sehr interessant.

Auf den ersten Blick vielleicht. Sie offenbart ihre Nachteile, wenn noch mehr Werte als drei gesucht werden. Es werden nämlich n-1 Selfjoins und n Bedingungen benötigt. Man muss das Statement zwingend anhand dieser Gegebenheiten zusammenbauen. Die HAVING-COUNT-Lösung käme auch mit Subquerys für die Werte in IN() und die Anzahl aus.

Das nächste Problem wird sein, dass hier eine Zwischenmenge aus sehr vielen Datensätzen gebaut wird. Für jeden Wert von a werden count(a) hoch Anzahl(Suchwerte) Zeilen erzeugt. Für den gegebenen Fall sind das bei a=1 und 5 jeweils 4^3 = 64 Zeilen, bei 2, 3 und 4 jeweils 2^3 = 8. Macht bei den wenigen Beispieldaten schon 152 Zeilen. Ein Suchbegriff mehr macht 544 und noch einer sind schon 2112 Zeilen.

Und das wird sicher nicht besser, wenn die Query gegen die echten Daten laufen galassen wird. Bei kleinen Tabellengrößen mag das noch gehen, bei großen wird es immer ungünstiger. Was du aber noch machen kannst: die Query noch komplexer, indem du zu jeder Join-Bedingung das schon bekannte IN() mit den Suchwerten hinzufügst, was die Anzahl der möglichen Kombinationen von b einschränkt.

Was dahinter steckt ist die Normalisierung (jaja, immer wieder dasselbe, danke Herr Codd).
Allgemein: Bei einer 1:n Beziehung braucht es zwei Tabellen. Bei einer n:m Beziehung braucht es eine Tabelle mehr, also drei.

Diese Begründung passt nicht. Es geht hier lediglich um die Beziehungstabelle. Für das eigentliche Problem ist nicht weiter relevant, dass sie eine solche ist, ebensowenig wie ihre Beziehungen zu anderen Tabellen. Von den anderen Tabellen könnte lediglich eine ins Spiel kommen, wenn es darum geht, die Suchwerte direkt statt ihrer IDs anzugeben. Dann könnte man die beiden Tabellen mit einen Join verbinden, das IN() in die zweite Tabelle verlagern, dort die eigentlichen Suchwerte anzugeben und damit statt mit deren IDs in der jetzigen Tabelle zu suchen. Das löst nur das grundlegende Problem nicht. Es fügt nur noch viel mehr Komplexität hinzu, weil die b-Tabelle zu jedem Self-Join hinzugejoint werden muss.

Mit dem SELF-Join erzeugst Du diese 3 Tabellen, die referentielle Integrität läuft dazu über das Feld 'a' und die Bedingungen in der Whereklause können nun mit AND verknüpft werden, weil drei Tabellen gegeben sind.

Fachwort-Bullshit-Bingo. "Referenzielle Integrität" ist, wenn die IDs in a und b auf Gegenstücke in den anderen Tabellen zeigen und nicht in der Luft hängen. Das hat mit dem vorliegenden Problem nichts weiter zu tun. Sie kommt erst ins Spiel, wenn die Gegenstücke zu a und b benötigt werden.

Die Zahl 3 ist nur zufällig dieselbe bei "Anzahl der Tabellen einer n:m-Beziehung" und der Anzahl der hier benötigten Selfjoin-Tabellen. Letztere korreliert mit der Anzahl der Suchbegriffe, ist also eine beliebige Zahl. "Diese drei Tabellen" sind letztlich nur eine von den drei m:n-Tabellen, diese wird jedoch weniger, gleich oder mehr als dreimal verwendet.

Die Bedingungen "können nun mit AND verknüpft werden", weil du durch die Selfjoins die "senkrechten" Daten in die "Waagerechte" gebracht hast. Mit den oben genannten Nachteilen der Datensatzvervielfältigung dieser Variante.

Allerdings denke ich, es ist bei der dynamischen Abfrage eher schlechter als die andere Lösung, da man hier, so würde ich es machen, mit zwei Schleifen die Unterabfrage aufbauen müsste (die zwei joins, wo man so etwas wie join tab as x_i bräuchte, und die Bedingungen x_0 = 1 and x_1 = 3 etc. Ich denke, das ist sehr unübersichtlich, aber für nichtdynamische Sachen ist es auf jeden Fall (be)merkenswert, auch dafür danke.

So ist es. Das Statement ist viel umständlicher zu erzeugen und mit mehr Nachteilen als die HAVING-COUNT-Lösung behaftet.

dedlfix.