Logische Verknüpfungen in M:N Tabellen kannst du auf 2 Arten realisieren:
*AND by X-Join*
SELECT a.user_id
FROM user_attribut a, user_attribut b
WHERE a.attribut_id=2 AND b.attribut_id=5
AND a.user_id=b.user_id
*AND by having*
SELECT user_id,count(user_id) as anz
FROM user_attribut
WHERE attribut_id in(2,5)
GROUP BY user_id HAVING anz=2
Wobei zu sagen währe das ein X-Join meist schneller ist, und auch noch
andere logische Verknüpfungen zulässt.
Allerdings bei 1.000.000 Artikeln währe es Ratsam noch eine weitere
Einschränkung in die M:N-Tabelle einzubauen. (Etwa eine Kategorie). Da
bei hoher Selektivität der Attribute, die Abfragen schon etwas dauern
können.
Effiziente Indiezes sind hier natürlich sehr wichtig.
> Kann mir jemand ein evlt. ein paar brauchbare Lösungsansätze liefern?
> Oder auch ein paar SuMa(Google)-Links?
Eine richtiges Suchmaschinen-Framework währe z.B. Lucene. Mit der
php-Implementation, welche im ZEND-Framework enthalten ist, habe ich
aber schlechte Erfahrungen. Diese hatte unter php 5.2 erhebliche
Speicherprobleme. Und war schon mit einem relativ geringen Datenbestand
nicht mehr benutzbar.
Allerdings ist die Originale Java-Implementation davon sehr zu empfehlen.
Achtung! Ich setzte hier einen Xpost und Fup nach dclpd, da das ganze
IMHO dort besser aufgehoben ist.
Grüße,
Harald
> SELECT a.user_id
> FROM user_attribut a, user_attribut b
> WHERE a.attribut_id=2 AND b.attribut_id=5
> AND a.user_id=b.user_id
Ich bevorzuge mittlerweile "echte" JOINs:
SELECT a.user_id
FROM user_attribut a JOIN user_attribut b ON a.user_id = b.user_id
WHERE a.attribut_id = 2 AND b.attribut_id = 5
> SELECT user_id,count(user_id) as anz
> FROM user_attribut
> WHERE attribut_id in(2,5)
> GROUP BY user_id HAVING anz=2
Das geht auch ohne das teure HAVING:
SELECT user_id, COUNT(user_id) AS anz
FROM user_attribut
WHERE attribut_id IN (2,5) AND COUNT(user_id) = 2
Allerdings frage ich mich gerade, was das alles mit PHP zu tun hat.
Gruß. Claus
Ich auch, denn ansonsten muss man die Query spätestens dann umbauen,
wenn z.B. ein LEFT JOIN dazu kommt.
>> SELECT user_id,count(user_id) as anz
>> FROM user_attribut
>> WHERE attribut_id in(2,5)
>> GROUP BY user_id HAVING anz=2
>
> Das geht auch ohne das teure HAVING:
>
> SELECT user_id, COUNT(user_id) AS anz
> FROM user_attribut
> WHERE attribut_id IN (2,5) AND COUNT(user_id) = 2
Komisch, ich bekomme da "Invalid use of group function". Selbst mit
angefügtem GROUP BY user_id.
> Allerdings frage ich mich gerade, was das alles mit PHP zu tun hat.
Du musst das im Kontext sehen ;-P
>> SELECT user_id,count(user_id) as anz
>> FROM user_attribut
>> WHERE attribut_id in(2,5)
>> GROUP BY user_id HAVING anz=2
>
> Das geht auch ohne das teure HAVING:
>
> SELECT user_id, COUNT(user_id) AS anz
> FROM user_attribut
> WHERE attribut_id IN (2,5) AND COUNT(user_id) = 2
Nein, eben nicht. IIRC ist das, weil WHERE ausgewertet werden muss,
*bevor* die Ergebnismenge feststeht, wäre ja auch logisch, weil es dazu
benötigt wird, *um* die Ergebnismenge zu ermitteln.
Eine Aggregatfunktion kann aber dann erst auf die Ergebnismenge
angewendet werden. Deswegen gibt es ja HAVING.
Gruß, Helmut
--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---
> Eine Aggregatfunktion kann aber dann erst auf die Ergebnismenge
> angewendet werden. Deswegen gibt es ja HAVING.
Stimmt. Habe die entsprechende Stelle im Handbuch gefunden:
,----------[MySQL 5.1 Referenzhandbuch, 13.2.7 SELECT]
| Die HAVING-Klausel kann Zusammenfassungsfunktionen referenzieren, was
| der WHERE-Klausel nicht möglich ist
`----------
War mir noch nicht bekannt. Nun ja, wieder was gelernt :-)
Gruß. Claus