SQL-Loesung fuer komplexe Bedingungs-Aufloesung
am 15.02.2006 16:49:00 von niels.froehlingHallo;
Ich versuche die Aufloesung komplexer Ein/Auschluss-Kriterien
zur Auswahl passender Daten per SQL zu loesen, dabei geht es um
Auschluesse folgender Art (bewusst flasches und konzeptionelles
SQL):
SELECT e.`inhalt`
FROM `eintraege` e, `konditionen` k
WHERE
(e.id = k.eintrag)
AND
(
IF NOT EXISTS(kondition fuer den k.`wert` = 'farbe') OR
IF EXISTS('meinfarbwert' REGEXP k.`vergleich`)
)
AND
(
IF NOT EXISTS(kondition fuer den k.`wert` = 'textur') OR
IF EXISTS('meintexturewert' REGEXP k.`vergleich`)
)
AND
(
IF NOT EXISTS(kondition fuer den k.`wert` = 'temperatur') OR
IF EXISTS('meintemperaturwert' REGEXP k.`vergleich`)
)
...
Ich kann das programmatisch recht einfach loesen, dann muss
ich aber so ziemlich alle Eintraege + Konditionen durchgehen,
die Loesung ist aber in einer interpretativen Sprache, somit
seeeehr viel langsamer als mySQL.
Ich koennte 'IF (NOT) EXISTS' per Sub-Select realisieren wenn
ich Sub-Selects haette, muss aber zu mySQL 3.?? (weiss ich nicht,
weil sich die Kunden manchmal Server besorgen, die 3er Version
ist die aelteste, die bisher aufgetaucht ist) kompatibel sein.
Ich koennte 'IF (NOT) EXISTS' per JOIN realisieren wenn die
'wert'-Menge begrenzt waere:
SELECT e.`inhalt`
FROM `eintraege` e, `konditionen` k
LEFT JOIN `konditionen` f ON
(e.id = f.eintrag) AND (f.`wert` = 'farbe')
LEFT JOIN `konditionen` t ON
(e.id = t.eintrag) AND (t.`wert` = 'textur')
LEFT JOIN `konditionen` u ON
(e.id = u.eintrag) AND (u.`wert` = 'temperatur')
WHERE
(e.id = k.eintrag)
AND
(
IF ISNULL(f.id) OR ('meinfarbwert' REGEXP k.`vergleich`)
)
AND
(
IF ISNULL(t.id) OR ('meintexturewert' REGEXP k.`vergleich`)
)
AND
(
IF ISNULL(u.id) OR ('meintemperaturwert' REGEXP k.`vergleich`)
)
...
allerdings sehe ich Probleme das fuer die JOINS benoetigte GROUP
BY einzufuegen, ganz zu schweigen davon, dass eine Konditions-Menge
von 666 natuerlich 666 JOINS produziert (nun, die Sub-Select Variante
fuehrt natuerlich zu 666 Sub-Selects).
Nun fallen mir zur Loesung des Problems nur noch mehr oder minder
krude Hacks ein, so z.B. die Erzeugung von dummy-Eintraegen, die
allerdings das Daten-Aufkommen und die Menge an durchzufuehrenden
Vergleichen noch gewaltig erhoehen.
Hier mal Beispiel-Tabellen:
CREATE TABLE `tstEintrag` (
`id` int(11) NOT NULL auto_increment,
`inhalt` varchar(255) NOT NULL default 'abc',
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=2 ;
INSERT INTO `tstEintrag` VALUES (1, 'nicht fuer rot-gruen blinde');
CREATE TABLE `tstKondition` (
`id` int(11) NOT NULL auto_increment,
`eintrag` int(11) NOT NULL default '0',
`wert` varchar(255) NOT NULL default '',
`vergleich` varchar(255) NOT NULL default '',
PRIMARY KEY (`id`)
) TYPE=MyISAM AUTO_INCREMENT=2 ;
INSERT INTO `tstKondition` VALUES (1, 1, 'farbe', '(gruen|rot)');
Ich hoffe jemand hat eine Idee, Umstrukturierung, Mahnung. Mein
Ansatz ist/war vollstaendige Abstraktion der Konditionen, keine
vordefinierten Abhaengigkeiten.
Ciao und danke
Niels