sticky bit
24-05-2005, 17:06
Ich habe da ein Problem bzgl. eines Querys auf ner Oracle 8i.
Am besten ich erläutere es an einem Beispiel.
Also stellt Euch vor ich habe eine Tabelle, nennen wir sie `foo`, deren Inhalt der Spalte `bar` mit verschiedenen Werten gefüllt ist, etwa so:
.__________.
| bar |
+----------+
| Hose |
| Rock |
| Hemd |
| Tisch |
| Hund |
| Katze |
| Maus |
| Rechner |
| Mann |
| Frau |
| Papier |
| Holz |
| Stahl |
| Glas |
| Stuhl |
| Bett |
| Schrank |
| Telefon |
| Buch |
| Stift |
| Baum |
| Haus |
| Auto |
| Stiefel |
| Muetze |
+----------+
Aus dieser Tabelle möchte ich nun eine Menge erhalten, die zum einen bestimmte Bedingungen erfüllt, also nehmen wir als Bsp. alles wo `bar` kleiner gleich 4 Buchtstaben in der Länge ist, und das ganze auf 5 Tupel limitieren. Ausserdem soll sortiert werden, etwa nach `bar`.
Insgesamt sehe der Beispiel-Query also z. B. so aus:
SELECT bar
FROM foo
WHERE LENGTH(bar) <= 4 AND
rownum <= 5
ORDER BY bar;
Dieser würde nun allerdings folgendes liefern:
.__________.
| bar |
+----------+
| Hemd |
| Hose |
| Hund |
| Maus |
| Rock |
+----------+
Man sieht also, dass anscheinend zuerst die Limitierung auf die 5 Tupel greift (rownum <= 5) und dann erst die Sortierung (ist ja auch nicht unlogisch), aber genau da liegt mein Problem, die Menge die ich bräuchte sollte eben zuerst sortiert und dann erst auf ihre Tupelanzahl eingeschränkt werden.
So dass eben sowas dabei rauskommt:
.__________.
| bar |
+----------+
| Auto |
| Baum |
| Bett |
| Buch |
| Frau |
+----------+
Bisher fällt mir eigentlich nur eine Möglichkeit ein, nämlich zuerst alles in eine Unterabfrage zu packen und sortieren und dann erst eine beschränkte Anzahl Tupel aus der Menge der Unterabfrage wieder abfragen. Würde dann also so aussehen:
SELECT bar
FROM (SELECT bar
FROM foo
WHERE LENGTH(bar) <= 4
ORDER BY bar)
WHERE rownum <= 5;
Funktioniert zwar, macht aber alles grottenlangsam.
Es ist ja nur ein stark reduziertes Beispiel, der Query um den es eigentlich geht ist recht kompliziert und ohnehin nicht gerade schnell und es geht ausserdem um einige 10K Datensätze...
Also vielleicht fällt jemanden ja ne Möglichkeit ein das irgendwie effizient zu lösen?
Am besten ich erläutere es an einem Beispiel.
Also stellt Euch vor ich habe eine Tabelle, nennen wir sie `foo`, deren Inhalt der Spalte `bar` mit verschiedenen Werten gefüllt ist, etwa so:
.__________.
| bar |
+----------+
| Hose |
| Rock |
| Hemd |
| Tisch |
| Hund |
| Katze |
| Maus |
| Rechner |
| Mann |
| Frau |
| Papier |
| Holz |
| Stahl |
| Glas |
| Stuhl |
| Bett |
| Schrank |
| Telefon |
| Buch |
| Stift |
| Baum |
| Haus |
| Auto |
| Stiefel |
| Muetze |
+----------+
Aus dieser Tabelle möchte ich nun eine Menge erhalten, die zum einen bestimmte Bedingungen erfüllt, also nehmen wir als Bsp. alles wo `bar` kleiner gleich 4 Buchtstaben in der Länge ist, und das ganze auf 5 Tupel limitieren. Ausserdem soll sortiert werden, etwa nach `bar`.
Insgesamt sehe der Beispiel-Query also z. B. so aus:
SELECT bar
FROM foo
WHERE LENGTH(bar) <= 4 AND
rownum <= 5
ORDER BY bar;
Dieser würde nun allerdings folgendes liefern:
.__________.
| bar |
+----------+
| Hemd |
| Hose |
| Hund |
| Maus |
| Rock |
+----------+
Man sieht also, dass anscheinend zuerst die Limitierung auf die 5 Tupel greift (rownum <= 5) und dann erst die Sortierung (ist ja auch nicht unlogisch), aber genau da liegt mein Problem, die Menge die ich bräuchte sollte eben zuerst sortiert und dann erst auf ihre Tupelanzahl eingeschränkt werden.
So dass eben sowas dabei rauskommt:
.__________.
| bar |
+----------+
| Auto |
| Baum |
| Bett |
| Buch |
| Frau |
+----------+
Bisher fällt mir eigentlich nur eine Möglichkeit ein, nämlich zuerst alles in eine Unterabfrage zu packen und sortieren und dann erst eine beschränkte Anzahl Tupel aus der Menge der Unterabfrage wieder abfragen. Würde dann also so aussehen:
SELECT bar
FROM (SELECT bar
FROM foo
WHERE LENGTH(bar) <= 4
ORDER BY bar)
WHERE rownum <= 5;
Funktioniert zwar, macht aber alles grottenlangsam.
Es ist ja nur ein stark reduziertes Beispiel, der Query um den es eigentlich geht ist recht kompliziert und ohnehin nicht gerade schnell und es geht ausserdem um einige 10K Datensätze...
Also vielleicht fällt jemanden ja ne Möglichkeit ein das irgendwie effizient zu lösen?