Hi Vinzenz!
Nochmal ein Dankeschön für deine Erläuterungen.
bitte, gerne. Ich bin noch nicht fertig.
Ich schaff´ dich schon noch! ;-)
Jetzt ist mir auch die Funktionsweise von HAVING (wieder) klar.
Ja, ich war verwundert. Ich dachte, Du beherrschtest das :-)
Im Auswendiglernen war ich nie besonders gut.
Und so oft musste ich das noch nicht einsetzen. Dafür bin ich jetzt um ein Erfahrung reicher, and I am not having
any problems with HAVING
anymore.™ =)
zurück zu Deinem Ausgangsproblem. Du hattest - was gelegentlich vorkommt - Dein Problem zu stark reduziert.
Ich hatte es soweit reduziert, weil ich ja schon eine Lösung hatte und irgendwie nur darauf fixiert war, die Aufgabe mit GROUP BY zu lösen.
Nach einem anderen Lösungsweg _wollte_ ich ja gar nicht suchen.
Aber irgendwie habe ich auf einen dieser genialen Schubser gehofft, die man wirklich nur in diesem Forum bekommt.
Aufgrund des speziellen Verhaltens von NULL-Werten: Der Vergleich mit dem Gleichheitsoperator zwischen NULL und NULL liefert NULL.
Tipp dazu: prüfe im Client Deiner Wahl folgendes:
SELECT NULL = NULL test
Nää! Die Wertetabelle (true, false, null) x (true, false, null) hab´ ich sogar noch im Kopf. :-P
NULL ist nicht wahr, somit sind Deine Zeilen mit NULL-Werten eh' schon draußen [...]
Und selbst wenn dem nicht so wäre, könnte ich sie in der Unterabfrage immer noch ausschließen.
Danke für deine Hilfe.
Ich kann ja noch schildern, wofür das ganze Gedöns überhaupt gut ist und du kannst dann beurteilen, ob ich gleich vollständig mit der Sprache hätte rausrücken sollen. ;-)
Die SQL-Abfrage benötige ich für ein Volltext-Such-Addon für das CMS Redaxo.
In Redaxo gibt es Artikel, die durch das Addon indexiert werden. Außerdem bietet das Addon die Möglichkeit, beliebige Datenbankspalten ebenfalls zu indexieren. Dabei kann es vorkommen, dass in einem Suchergebnis auch Datensätze aus Datenbankspalten enthalten sind, die zu einem Artikel gehören, der auch gefunden wurde. Diese DB-Spalten und die indexierten Artikel, können über die Artikel-ID eindeutig einem Artikel zugeordnet werden.
Meine Anforderung an die SQL-Abfrage war jetzt, dass dann der Datensatz mit der höchsten Relevanz das Rennen macht.
Die NULL-Werte folgen aus der Flexibilität des Addons. Da beliebige Datenbankspalten indexiert werden können, sind manche dieser Spalten eben nicht mit einem Artikel über dessen ID verknüpft, sondern haben an dieser Stelle einfach einen (in diesem Sinne definierten) NULL-Wert.
Da das Addon in diesem Fall nicht entscheiden kann, ob diese Datensätze in irgendeiner Weise zusammengehören, müssen alle zurückgegeben werden.
Eine Variante der Abfrage könnte dann z. B. so aussehen:
SELECT ((( MATCH (`plaintext`) AGAINST ('suche')) * 1) + (( MATCH (`plaintext`) AGAINST ('diesen')) * 1) + (( MATCH (`plaintext`) AGAINST ('begriff')) * 1) + 1) AS RELEVANCE587,
id,
fid, -- fid und
catid,
ftable, -- ftable
fcolumn, -- bestimmen die eindeutige Zugehörigkeit zu einem
texttype, -- Artikel (oder ähnlichen Objekten, die es in Redaxo gibt)
clang,
unchangedtext,
plaintext,
teaser
FROM `rex_587_searchindex` r1
WHERE (
(
(
(
`plaintext` LIKE '%suche%'
)
)
AND (
(
`plaintext` LIKE '%diesen%'
)
)
AND (
(
`plaintext` LIKE '%begriff%'
)
)
)
)
AND (
((( MATCH (`plaintext`) AGAINST ('suche')) * 1) + (( MATCH (`plaintext`) AGAINST ('diesen')) * 1) + (( MATCH (`plaintext`) AGAINST ('begriff')) * 1) + 1)
=
(SELECT MAX((( MATCH (`plaintext`) AGAINST ('suche')) * 1) + (( MATCH (`plaintext`) AGAINST ('diesen')) * 1) + (( MATCH (`plaintext`) AGAINST ('begriff')) * 1) + 1)
FROM `rex_587_searchindex` r2
WHERE r1.ftable = r2.ftable
AND r1.fid = r2.fid
)
)
OR fid IS NULL
ORDER BY RELEVANCE587 DESC LIMIT 0,20
Das meiste dieser Abfrage wird dynamisch zusammengesetzt. Der Grundbaustein sieht im Grunde folgendermaßen aus (Formatstring für sprintf):
SELECT %s
FROM `%s` r1
WHERE (
%s
)
AND (
%s =
(SELECT MAX(%s)
FROM `%s` r2
WHERE r1.ftable = r2.ftable
AND r1.fid = r2.fid
)
)
OR fid IS NULL
ORDER BY %s LIMIT %d,%d
Wenn du jetzt weitere Verbesserungsvorschläge hast, würde ich mich natürlich weiterhin freuen, diese einzubeziehen.
Wenn du allerdings die gesamte Abfrage über den Haufen schmeißen würdest, dann hörst du die nächsten drei Monate nichts mehr von mir. Ich werde mich dann irgendwo auf einen hohen Berg setzen und meine verbliebenen Haare zählen.
In diesem Sinne
gute Nacht,
H☼psel
"It's amazing I won. I was running against peace, prosperity, and incumbency."
George W. Bush speaking to Swedish Prime Minister unaware a live television camera was still rolling, June 14, 2001
Selfcode: ie:% fl:( br:> va:) ls:& fo:) rl:? n4:& ss:| de:] js:| ch:? sh:( mo:) zu:)