Kombinierte Abfrage
am 12.05.2006 10:29:51 von Matthias Coy
Hi,
Ich bastel mir gerade eine Umfrage. Dabei such ich zur aktuell
gestellten Frage immer den Vorgänger, die aktuelle Frage und den
Nachfolger, um halt durchlaufen zu können. Den Vorgänger hole ich mir
beispielsweise so:
SELECT `id` , `frage`
FROM `fragen`
WHERE `umfrageId` = 1
AND `id` < 120
ORDER BY `id` DESC
LIMIT 1 ;
--> RESULT: `id` = 117
wobei 120 die ID der aktuellen Frage ist und 117 der Vorgänger. Jetzt
hätt ich aber gerne den Vorgänger dessen Antwort noch nicht in der
Antworten-Tabelle ist, also noch eine Abhängigkeit von dieser Abfrage
(grob formuliert):
SELECT `id`
FROM `antworten`
WHERE `frageId` = 117
LIMIT 1;
wenn da eine Reihe zrückkommt, müsste die obere Abfrage nochmal
gestartet werden, mit eben jener 117. Im schlimmsten Falle würde das
dann aber durch die ganze Tabelle wackeln auf der Suche nach dem
Vorgänger, der eventuell noch nicht mal existiert, weil alle Vorgänger
der aktuellen Frage beantwortet wurden. Wenn ich vorher 1000 Fragen
hatte, dann finde ich das irgendwie nicht besonders performant.
Welche Lösung wäre hier praktikabel?
MfG
Matthias Coy
Re: Kombinierte Abfrage
am 12.05.2006 10:52:26 von Christian Kirsch
Matthias Coy schrieb:
> Hi,
>
> Ich bastel mir gerade eine Umfrage. Dabei such ich zur aktuell
> gestellten Frage immer den Vorgänger, die aktuelle Frage und den
> Nachfolger, um halt durchlaufen zu können.
Wann willst Du durch was durchlaufen? Warum suchst Du die aktuelle
Frage (2. Satz), wenn Du die doch schon hast (1. Satz)?
Bitte frag' doch hier so, dass auch jemand außerhalb *deines* Gehirns
versteht, was Du eigentlich erreichen willst:
- Welches Problem möchtest Du in der realen Welt lösen?
- Welche Daten hast Du?
- Welche Teilmenge davon interessiert Dich?
- Wie sehen die Tabellen *genau* aus (SHOW CREATE TABLE!)
- Wie hängen sie zusammen?
> Den Vorgänger hole ich mir
> beispielsweise so:
>
> SELECT `id` , `frage`
> FROM `fragen`
> WHERE `umfrageId` = 1
> AND `id` < 120
> ORDER BY `id` DESC
> LIMIT 1 ;
>
> --> RESULT: `id` = 117
>
Diese Abfrage lässt vermuten, dass der 'Vorgänger' zu einer Frage
irgendwie flexibel ist - dass also heute 117 der Vorgänger von 120
ist, morgen aber vielleicht 100 oder 119. Ist das so? Warum?
Vielleicht möchtest Du einen Baum in SQL abbilden? Dann solltest Du
nach dem Thema mal googeln, dafür gibt es Lösungen.
> wobei 120 die ID der aktuellen Frage ist und 117 der Vorgänger. Jetzt
> hätt ich aber gerne den Vorgänger dessen Antwort noch nicht in der
> Antworten-Tabelle ist, also noch eine Abhängigkeit von dieser Abfrage
> (grob formuliert):
>
Du meinst also oben den 'direkten Vorgänger' (ohne das zu sagen). Und
jetzt sucht Du irgendeinen Vorgänger, der eine bestimmte Bedingung
erfüllt?
Im konkreten Fall könnte Dich ein Subselect mit 'NOT IN' interessieren
> SELECT `id`
> FROM `antworten`
> WHERE `frageId` = 117
> LIMIT 1;
>
LIMIT ohne ORDER BY ist zweckfrei. Das hatten wir hier neulich erst.
> wenn da eine Reihe zrückkommt, müsste die obere Abfrage nochmal
> gestartet werden, mit eben jener 117. Im schlimmsten Falle würde das
> dann aber durch die ganze Tabelle wackeln auf der Suche nach dem
> Vorgänger, der eventuell noch nicht mal existiert, weil alle Vorgänger
> der aktuellen Frage beantwortet wurden. Wenn ich vorher 1000 Fragen
> hatte, dann finde ich das irgendwie nicht besonders performant.
>
> Welche Lösung wäre hier praktikabel?
Keine Ahnung. Ich verstehe noch nichtmal genau Dein Datenmodell, viel
weniger, was Du eigentlich erreichen willst...
Ins Unreine gesprochen, würde ich Vorgänger und Nachfolger entweder
gar nicht kodieren (und auto_increment benutzen). Oder sie mit
geeigneten Feldern in der Tabelle selbst ablegen -> Bäume.
Re: Kombinierte Abfrage
am 12.05.2006 11:15:38 von Matthias Coy
Christian Kirsch schrieb:
> Matthias Coy schrieb:
>> Hi,
>>
>> Ich bastel mir gerade eine Umfrage. Dabei such ich zur aktuell
>> gestellten Frage immer den Vorgänger, die aktuelle Frage und den
>> Nachfolger, um halt durchlaufen zu können.
>
> Wann willst Du durch was durchlaufen? Warum suchst Du die aktuelle
> Frage (2. Satz), wenn Du die doch schon hast (1. Satz)?
Weil das Ergebnis vom 1.Satz eventuell das falsche ist, weil es
eigentlich vom 2.Satz abhängt
> Bitte frag' doch hier so, dass auch jemand außerhalb *deines* Gehirns
> versteht, was Du eigentlich erreichen willst:
>
> - Welches Problem möchtest Du in der realen Welt lösen?
> - Welche Daten hast Du?
> - Welche Teilmenge davon interessiert Dich?
> - Wie sehen die Tabellen *genau* aus (SHOW CREATE TABLE!)
> - Wie hängen sie zusammen?
Ich habe eine Umfrage. In dieser Umfrage sind mehrere Fragen. Ich möchte
zum durchlaufen der Fragen ("vorherige Frage", "nächste Frage"), eben
den Vorgänger und den Nachfolger haben. Diese definieren sich dadurch
das sie existieren und noch nicht beantwortet wurden. Ich möchte also
den Vorgänger/Nachfolger zur aktuelle Frage die noch nicht beantwortet
wurden
>> Den Vorgänger hole ich mir
>> beispielsweise so:
>>
>> SELECT `id` , `frage`
>> FROM `fragen`
>> WHERE `umfrageId` = 1
>> AND `id` < 120
>> ORDER BY `id` DESC
>> LIMIT 1 ;
>>
>> --> RESULT: `id` = 117
>>
>
> Diese Abfrage lässt vermuten, dass der 'Vorgänger' zu einer Frage
> irgendwie flexibel ist - dass also heute 117 der Vorgänger von 120
> ist, morgen aber vielleicht 100 oder 119. Ist das so? Warum?
> Vielleicht möchtest Du einen Baum in SQL abbilden? Dann solltest Du
> nach dem Thema mal googeln, dafür gibt es Lösungen.
Das ist so, weil der Vorgänger eventuell bereits beantwortet ist. Siehe
oben.
>> wobei 120 die ID der aktuellen Frage ist und 117 der Vorgänger. Jetzt
>> hätt ich aber gerne den Vorgänger dessen Antwort noch nicht in der
>> Antworten-Tabelle ist, also noch eine Abhängigkeit von dieser Abfrage
>> (grob formuliert):
>>
> Du meinst also oben den 'direkten Vorgänger' (ohne das zu sagen). Und
> jetzt sucht Du irgendeinen Vorgänger, der eine bestimmte Bedingung
> erfüllt?
> Im konkreten Fall könnte Dich ein Subselect mit 'NOT IN' interessieren
So hab ich das jetzt auch gelöst.
>> SELECT `id`
>> FROM `antworten`
>> WHERE `frageId` = 117
>> LIMIT 1;
>>
>
> LIMIT ohne ORDER BY ist zweckfrei. Das hatten wir hier neulich erst.
Danke für den Hinweis.
>> wenn da eine Reihe zrückkommt, müsste die obere Abfrage nochmal
>> gestartet werden, mit eben jener 117. Im schlimmsten Falle würde das
>> dann aber durch die ganze Tabelle wackeln auf der Suche nach dem
>> Vorgänger, der eventuell noch nicht mal existiert, weil alle Vorgänger
>> der aktuellen Frage beantwortet wurden. Wenn ich vorher 1000 Fragen
>> hatte, dann finde ich das irgendwie nicht besonders performant.
>>
>> Welche Lösung wäre hier praktikabel?
>
> Keine Ahnung. Ich verstehe noch nichtmal genau Dein Datenmodell, viel
> weniger, was Du eigentlich erreichen willst...
> Ins Unreine gesprochen, würde ich Vorgänger und Nachfolger entweder
> gar nicht kodieren (und auto_increment benutzen). Oder sie mit
> geeigneten Feldern in der Tabelle selbst ablegen -> Bäume.
Prinzipiell hab ich doppelt verkette Liste, ohne diese in der Datenbank
zu haben. Das ist schon ein Denkfehler der mir jetzt eben oben genanntes
Problem bereitet.
Gruß
Matthias Coy
Re: Kombinierte Abfrage
am 12.05.2006 12:38:16 von Christian Kirsch
Matthias Coy schrieb:
> Christian Kirsch schrieb:
>> Matthias Coy schrieb:
>>> Hi,
>>>
>>> Ich bastel mir gerade eine Umfrage. Dabei such ich zur aktuell
>>> gestellten Frage immer den Vorgänger, die aktuelle Frage und den
>>> Nachfolger, um halt durchlaufen zu können.
>> Wann willst Du durch was durchlaufen? Warum suchst Du die aktuelle
>> Frage (2. Satz), wenn Du die doch schon hast (1. Satz)?
> Weil das Ergebnis vom 1.Satz eventuell das falsche ist, weil es
> eigentlich vom 2.Satz abhängt
>> Bitte frag' doch hier so, dass auch jemand außerhalb *deines* Gehirns
>> versteht, was Du eigentlich erreichen willst:
>>
>> - Welches Problem möchtest Du in der realen Welt lösen?
>> - Welche Daten hast Du?
>> - Welche Teilmenge davon interessiert Dich?
>> - Wie sehen die Tabellen *genau* aus (SHOW CREATE TABLE!)
>> - Wie hängen sie zusammen?
> Ich habe eine Umfrage. In dieser Umfrage sind mehrere Fragen. Ich möchte
> zum durchlaufen der Fragen ("vorherige Frage", "nächste Frage"), eben
> den Vorgänger und den Nachfolger haben. Diese definieren sich dadurch
> das sie existieren und noch nicht beantwortet wurden. Ich möchte also
> den Vorgänger/Nachfolger zur aktuelle Frage die noch nicht beantwortet
> wurden
>
Was spricht denn überhaupt dagegen, die Fragen in einer bestimmten
Reihenfolge zu stellen und zu beantworten? Willst Du das im Netz
machen, mit je einem Vorige/Nächste-Knopf? Dann reicht doch ein
'AND ANTWORT IS NULL'
mit einem geeigneten Join, um die Auswahl auf die beantworteten zu
beschränken.
> Prinzipiell hab ich doppelt verkette Liste, ohne diese in der Datenbank
> zu haben. Das ist schon ein Denkfehler der mir jetzt eben oben genanntes
> Problem bereitet.
Dann korrigiere das Modell.