SQL 1 komplexe Abfrage aus 3 Querys zu einem Query machen?!

benneq

Fleet Admiral
Registriert
Juli 2010
Beiträge
12.620
Moin,

ich möchte meine Datenbank-Abfrage mal etwas vereinfachen bzw. für die Abfrage auch wirklich nur noch einen Query losschicken und nicht mehr 3. Das sollte ja auch im Interesse der Performance liegen. Ich habe soweit alle Tabellen so sehr vereinfach wie nur möglich:

Code:
table1:                   table2:                    table3:
id | text                 id | text                  id | table1id | table2id | text
----------                ----------                 --------------------------------
1  | abaac                1  | cabaa                 1  |   1      |   3      | abbba
2  | bbaca                2  | bacba                 2  |   2      |   2      | bcabc
3  | babaa                3  | abcba                 3  |   3      |   1      | abaab


Funktionsweise: Ich gebe einen String ein (im Folgenden $EINGABE$ genannt), der in allen 3 Tabellen gesucht wird und als erhalte ich die Liste von ids aus table3.


Aktuell sieht das grob so aus:
Abfrage für table1:
Code:
SELECT id FROM table1 WHERE text LIKE '%$EINGABE$%'
$ERGEBNIS1$ enthält alle ids aus table1 die passen.
Dann bau ich mir einen String zusammen, der in der letzten Abfrage benutzt wird:
Code:
for ($ERGEBNIS$ in $ERGEBNIS1$) {
    $WHERE1$ += 'OR (table3.table1id = $ERGEBNIS$)';
}


Abfrage für table2:
Code:
SELECT id FROM TABLE2 WHERE text LIKE '%$EINGABE$%'
$ERGEBNIS2$ enthält alle ids aus table2 die passen.
Dann bau ich mir einen String zusammen, der in der letzten Abfrage benutzt wird:
Code:
for ($ERGEBNIS$ in $ERGEBNIS2$) {
    $WHERE2$ += 'OR (table3.table2id = $ERGEBNIS$)';
}


Zum Schluss wird mein Query auf table3 ausgeführt und die Strings $WHERE1$ und $WHERE2$ eingebaut:
Code:
SELECT id FROM table3
  JOIN table1 ON table1.id = table3.table1id
  JOIN table2 ON table2.id = table3.table2id
WHERE text LIKE '%$EINGABE$%'
$WHERE1$
$WHERE2$




Beispiel: $EINGABE$ = 'aa', dann ist:
$ERGEBNIS1$ = [1,3]
-> $WHERE1$ = "OR (table3.table1id = 1) OR (table3.table1id = 3)"
$ERGEBNIS2$ = [1]
-> $WHERE2$ = "OR (table3.table2id = 1)"


Die resultierende Anfrage sieht dann so aus:
Code:
SELECT id FROM table3
  JOIN table1 ON table1.id = table3.table1id
  JOIN table2 ON table2.id = table3.table2id
WHERE text LIKE '%aa%'
OR (table3.table1id = 1)
OR (table3.table1id = 3)
OR (table3.table2id = 1)

Als Ergebnis erhalte ich dann: [1,3]




Also im Endeffekt würde ich die ersten 2 Querys gern direkt mit in die letzte DB-Anfrage einpflanzen. Die Frage ist gerade nur: WIE?
 
Zuletzt bearbeitet:
Was bezweckst du mit deiner momentanen OR Einschränkungen auf die Tableids?

Wieso nicht einfach in der Art:

SELECT t1.id, t2.id, t3.id FROM table1 AS t1
JOIN table2 AS t2 ON...
JOIN table3 as t3 ON...
WHERE t1.text LIKE... OR t2.text LIKE... OR t3.text LIKE...

Führt das zu einem unerwünschten Ergebnis?
 
Ich will am Ende nur(!) IDs aus table3 haben.

Das OR bezweckt, dass ich z.B. bei der Anfrage $EINGABE$ = 'abcba'
Als Ergebnis [1] bekomme, weil table3.id = 1, genau da wo table3.table2id = table2.id, mit table2.text = 'abcba'

Deine Abfrage würde mir ja ein 3-spaltiges Ergebnis bringen mit den IDs von table1, table2 und table3, die ich aber gar nicht möchte. Die IDs von table1 und table2 dienen nur als Key für die Foreign-Key-Beziehung von table3 -> table1 und table3 -> table2
 
Zuletzt bearbeitet:
Sehe das Problem immer noch nicht.

Dann machst du halt:

SELECT id FROM table3 as t3
{hier die Joins auf die anderen tables}
WHERE t1.text LIKE... OR t2.text LIKE... OR t3.text LIKE...

Edit:

Am besten du fängst erstmal mitm SELECT * FROM table3 an, machst die INNER JOINS auf die anderen beiden tables und gibst keine WHERE Bedingung an.
Wenn ich mich nicht verschätze, hast du dann 3 Zeilen mit id und text spalten von allen 3 tables.

Dadurch sollte schlüssig sein, wieso man mit der oben stehenden WHERE Bedingung die entspreche id von table3 bekommt.
 
Zuletzt bearbeitet:
Ach ****** ja :D

Ich hab wohl den Baum vor lauter Wald nicht gesehen.

Es ist wirklich so simpel:

Code:
SELECT DISTINCT id FROM table3
  JOIN table1 ON table1.id = table3.table1id
  JOIN table1 ON table2.id = table3.table2id
WHERE
  table1.text LIKE '%$EINGABE$%' OR
  table2.text LIKE '%$EINGABE$%' OR
  table3.text LIKE '%$EINGABE$%'

Danke (:

EDIT: Das DISTINCT hatte ich auch noch vergessen ;)
 

Ähnliche Themen

Antworten
14
Aufrufe
1.466
Zurück
Oben