Hallo,
Tabelle: word
ID | word
---+-----
1 | RETTE
2 | RETTER
3 | RETTEN
es ist ganz sicher aus Gründen der Leseoptimierung sinnvoll, die Zeichenlänge des Wortes (redundant) in einer eigenen Spalte abzuspeichern:
ID | word | length
---+---------+-------
1 | RETTE | 5
2 | RETTER | 6
3 | RETTEN | 6
Tabelle: word_letter
n = Häufigkeit der Buchstaben in dem WortID_word | letter | n
--------+--------+---
1 | R | 1
1 | E | 2
1 | T | 2
2 | R | 2
2 | E | 2
2 | T | 2
3 | R | 1
3 | E | 2
3 | T | 2
3 | N | 1
- Schritt:
nach der ersten Abfrage sollen alle "Wörter" mit einer bestimmten Länge übrig bleiben
die Abfrage dazu vereinfacht sich zu
SELECT -- Gib mir
ID, -- ID,
word -- wort
FROM -- aus der Tabelle
word -- word
WHERE -- wobei nur Wörter mit der
length = 6 -- Zeichenlänge 6 berücksichtigt werden sollen.
Dies ist ganz sicher performanter als ein Join mit Gruppierung und HAVING-Klausel, da sonst *alle* Datensätze berücksichtigt werden müssen.
und folgende Tabelle übergeben werden.
ID_word | letter | n
--------+--------+---
2 | R | 2
2 | E | 2
2 | T | 2
3 | R | 1
3 | E | 2
3 | T | 2
3 | N | 1
ein einfacher Join mit word_letter
SELECT -- Gib mir
w.ID ID_word, -- die IDs der Worte
wl.letter letter, -- die darin vorkommenden Buchstaben
wl.n n -- und ihre Anzahl
FROM -- aus der Tabelle
word w -- word (als w angesprochen),
INNER JOIN -- die mit der Tabelle
word_letter wl -- word_letter (als wl angesprochen)
ON -- über die Spalten
w.ID = wl.ID -- ID (in beiden Tabellen) verknüpft ist
WHERE -- wobei nur die Worte interessieren,
w.length = 6 -- die 6 Zeichen lang sind.
("RETTE" ist damit schonmal raus)
Diese "Tabelle" kann die Grundlage entweder diverser Selfjoins oder halt diverser Subselects sein. Da die Anzahl der Buchstaben jeweils unterschiedlich ist, kannst Du das dritte Beispiel nicht anwenden, sondern musst Dich mit dem zweiten begnügen :-(
- Schritt:
im zweiten Schritt bleiben noch alle Wörter, in denen "R" zweimal vorkommt:ID_word | letter | n
--------+--------+---
2 | R | 2
2 | E | 2
2 | T | 2
Was performanter ist:
Subselect über die ganze word_letter-Tabelle oder über obige Abfrage, das musst Du mit Deinen Daten selbst durchtesten (EXPLAIN hilft Dir dabei):
SELECT
w.word
FROM
word w
WHERE
w.length = 6
AND
w.ID IN (
SELECT
wl.ID
FROM
word_letter wl
WHERE
letter = 'R'
AND
n = 2
)
AND
w.ID IN (
SELECT
wl2.ID
FROM
word_letter wl2
WHERE
letter = 'E'
AND
n = 2
)
Beachte dabei die Hinweise im Handbuchkapitel Optimizing Subqueries, aber insbesondere den ersten Satz.
Freundliche Grüße
Vinzenz