[MySQL] Hilfe bei SELECT Query über drei Tabellen

-ben-

Mitglied
Hy zusammen!

Ich möchte folgende Abfrage machen:
Gib mir die "targetgrp_id" bei der hobby=Schwimmen UND hobby=Segeln UND interesse=Literatur UND interesse=Politik UND geschlecht=Männlich UND sprache=Deutsch

Als Resultat sollte ich "2" erhalten.

Wie muss ich das Query aufbauen? Geht das ohne Subqueries?

Vielen Dank im Voraus! Bin wirklich um jeden Input froh, da ich vor einem Rätsel stehe :(
 

Anhänge

  • tbl.png
    tbl.png
    25,2 KB · Aufrufe: 96
Das geht ohne Subquery, allerdings nicht sehr effizient:
Code:
SELECT
  targetgrp_id
FROM Targetgroup
JOIN Relation AS r1
  ON Targetgroup.targetgrp_id=r1.targetgrp_id
JOIN Relation AS r2
  ON Targetgroup.targetgrp_id=r2.targetgrp_id
JOIN Relation AS r3
  ON Targetgroup.targetgrp_id=r3.targetgrp_id
JOIN Relation AS r4
  ON Targetgroup.targetgrp_id=r4.targetgrp_id
JOIN Relation AS r5
  ON Targetgroup.targetgrp_id=r5.targetgrp_id
JOIN Relation AS r6
  ON Targetgroup.targetgrp_id=r6.targetgrp_id
WHERE r1.attribute_id=1
  AND r2.attribute_id=2
  AND r3.attribute_id=4
  AND r4.attribute_id=5
  AND r5.attribute_id=6
  AND r6.attribute_id=8
Da ich das Query nicht testen konnte, mußt Du es ggf. noch anpassen.

Gruß hpvw
 
oder einfach:
Code:
SELECT targetgrp_id FROM targetgroup WHERE targetgrp_id = "2"
spass bei seite, folgendes quiri tut's auch:
Code:
SELECT
  targetgroup.targetgrp_id
FROM (
    targetgroup
LEFT JOIN
  relation
ON
  targetgroup.targetgrp_id = relation.targetgrp_id
)
LEFT JOIN
  attributes
ON
  relation.targetgrp_id = attributes.attribute_id
WHERE
  attributes.key = "hobby"
AND
  attributes.value = "Schwimmen"
AND
  so on ...
 
Danke für eure Antworten!

Also ich finde das Query von _Bruce schöner und kompakter. Da ich das Query dynamisch in Java generieren muss, ist die ein grosser Vorteil für mich!

Welches der beiden ist denn effizienter? :rolleyes:
 
Das Query von _Bruce wird IMHO nicht funktionieren.

Bei einem Join wird jede Zeile aus der ersten Tabelle mit jeder Zeile aus der zweiten Tabelle verknüpft und dann werden die Zeilen entfernt, die der Bedingung hinter ON nicht genügen.

In dem Query von _Bruce entsteht also zunächst (vor Projektion und Selektion) eine Ergebnistabelle mit den Spalten aus allen Tabellen und genau so vielen Zeilen, wie in der Tabelle Relation vorhanden sind (abgesehen von dem Cut'n'Paste-Fehler ... ON relation.targetgrp_id = attributes.attribute_id ...).
Das Feld value aus Attributes kommt in jeder Zeile einmal vor, ebenso das Feld key (welches übrigends im Sinne der Normalisierung eine eigene Tabelle verdient hätte).
Die Selektion wird also in keiner Zeile zutreffen, da das Feld in einer Zeile nicht gleichzeitig mehrere Werte annehmen kann.

Das Query, welches ich gepostet habe, geht übrigends davon aus, dass Dir beim (dynamischen) Erstellen des Querys die attribute_id der gewünschten Zeilen aus der Tabelle Attributes, zum Beispiel aus einem vorangegangen Auswahldialog, bekannt sind. Sollten die Eingaben frei sein, muss natürlich jedesmal ein weiterer Join mit der Tabelle Attributes durchgeführt werden.

Dieses Query lässt sich ebenfalls dynamisch erzeugen, wenn es auch etwas umständlicher sein mag, da sowohl die Joins erzeugt werden müssen, als auch die Selektion.

Gruß hpvw
 
Hallo!

Nur mal so nebenbei....
wenn bei zwei gejointen Tabellen die "Join-Spalten" gleich lautet kann man auch einen ganz einfachen natural join statt einem equi-join machen:
Code:
 mysql> select * from tabA;
 +------+-------+
 | id   | value |
 +------+-------+
 |	1 |   100 |
 |	2 |   300 |
 +------+-------+
 2 rows in set (0.00 sec)
 
 mysql> select * from tabB;
 +------+-------------+
 | id   | description |
 +------+-------------+
 |	1 | Foo		 |
 |	2 | Bar		 |
 +------+-------------+
 2 rows in set (0.00 sec)
 
 mysql> select value, description from tabA natural join tabB;
 +-------+-------------+
 | value | description |
 +-------+-------------+
 |   100 | Foo		 |
 |   300 | Bar		 |
 +-------+-------------+
 2 rows in set (0.00 sec)
 
 mysql>

Gruß Tom
 
Thomas Darimont hat gesagt.:
Hallo!

Nur mal so nebenbei....
wenn bei zwei gejointen Tabellen die "Join-Spalten" gleich lautet kann man auch einen ganz einfachen natural join statt einem equi-join machen:
Da hast Du recht, aber Gewohnheiten lassen sich schwer ablegen :-(
Da ich Tabellennamen nur bei Fremdschlüsseln in Feldnamen wiederhole, bin ich es nicht gewohnt, dass zwei relevante Feldnamen gleich lauten.

Dem Threadersteller steht es selbstverständlich frei, eine andere JOIN-Syntax zu übernehmen.

Gruß hpvw
 
@hpvw

Dein vorgeschlagenes Query scheint zu funktionieren. Jedoch weiss ich die attribute_id nicht, sondern nur der key und der value der Attribute.

Irgend eine Idee? Mir ist inzwischen auch eine Lösung mit Subqueries recht. Hauptsache ich erhalte das gewünschte Resultat.

Danke & Gruss
ben
 
Ein Versuch ohne Subquery unter Berücksichtigung von Toms Hinweis:
Code:
SELECT
  targetgrp_id
FROM Targetgroup
NATURAL JOIN Relation AS r1
  NATURAL JOIN Attributes AS a1
NATURAL JOIN Relation AS r2
  NATURAL JOIN Attributes AS a2
NATURAL JOIN Relation AS r3
  NATURAL JOIN Attributes AS a3
NATURAL JOIN Relation AS r4
  NATURAL JOIN Attributes AS a4
NATURAL JOIN Relation AS r5
  NATURAL JOIN Attributes AS a5
NATURAL JOIN Relation AS r6
  NATURAL JOIN Attributes AS a6
WHERE a1.key LIKE "hobby"
    AND a1.value="Schwimmen"
  AND a2.key LIKE "hobby"
    AND a2.value="Segeln"
  AND a3.key LIKE "interesse"
    AND a3.value="Literatur"
  AND a4.key LIKE "interesse"
    AND a4.value="Politik"
  AND a5.key LIKE "geschlecht"
    AND a5.value="Männlich"
  AND a6.key LIKE "sprache"
    AND a6.value="Deutsch"
Ein deutlich einfacheres Query fällt mir auch mit Subquery im Moment nicht ein.

Da hier mehrfach mit der gleichen Tabelle verknüpft wird und somit die attribute_id mehrfach vorkommt, bin ich mir nicht sicher, ob der NATURAL JOIN hier richtig arbeitet. Wenn nicht das gewünschte Ergebnis kommt, musst Du doch wieder auf den normalen JOIN umstellen und die ON-Bedingungen wieder einfügen.

Gruß hpvw
 
Zurück