Tabelle auslesen via UNION
gondor
- datenbank
Hallo,
ich lese Einträge aus einer Tabelle wie folgt aus:
Erst kommen die Einträge mit...
1. alle top!=0 AND color=0 und status=expert
2. alle top=0 AND color!=0 und status=expert
3. alle top=0 AND color=0 und status=expert
4. alle status=basic
Tabelle:
id | top | color | type (basic, expert) | created on
1 | 1 | 0 | expert | 2009-01-05 15:54:26
2 | 2 | 0 | expert | 2009-01-06 15:54:26
3 | 3 | 0 | expert | 2009-01-04 15:54:26
4 | 2 | 0 | expert | 2009-01-06 15:54:26
5 | 0 | 0 | basic | 2009-01-07 15:54:26
5 | 0 | 1 | expert | 2009-01-16 15:54:26
6 | 0 | 0 | basic | 2009-01-09 15:54:26
7 | 0 | 2 | expert | 2009-01-12 15:54:26
8 | 0 | 0 | expert | 2009-01-06 15:54:26
9 | 0 | 1 | expert | 2009-01-08 15:54:26
10 | 0 | 3 | expert | 2009-01-04 15:54:26
11 | 0 | 2 | expert | 2009-01-03 15:54:26
12 | 0 | 0 | basic | 2009-01-08 15:54:26
13 | 0 | 1 | expert | 2009-01-06 15:54:26
Meine Query dazu:
(
SELECT *
FROM table
WHERE top!=0 AND color=0 AND type='expert' ORDER BY created_on DESC
UNION
(
SELECT *
FROM table
WHERE top=0 AND color!=0 AND type='expert' ORDER BY created_on ASC
)
UNION
(
SELECT *
FROM table
WHERE top=0 AND color=0 AND type='expert' ORDER BY created_on ASC
)
UNION
(
SELECT *
FROM table
WHERE type='basic' ORDER BY created_on ASC
)
LIMIT 0, 100
Leider funktioniert das nicht, da die Einträge nicht wie gewollt nach Datum (oder was anderem) sortiert werden...
Jemand eine Idee, wieso?
Danke,
gondor
Hi,
Leider funktioniert das nicht, da die Einträge nicht wie gewollt nach Datum (oder was anderem) sortiert werden...
Doch, werden sie - innerhalb der einzelnen Selects natuerlich, denn da hast du angegeben, dass sortiert werden soll.
Jemand eine Idee
Ja - RTFM :-)
MfG ChrisB
yo,
Doch, werden sie - innerhalb der einzelnen Selects natuerlich, denn da hast du angegeben, dass sortiert werden soll.
wenn ich die doku richtig verstanden habe, wird genau das nicht passieren, sieht so aus, als wenn es nur in kombination mit LIMIT geht.
[Link:http://dev.mysql.com/doc/refman/5.1/de/union.html]
Ilja
Hi,
Doch, werden sie - innerhalb der einzelnen Selects natuerlich, denn da hast du angegeben, dass sortiert werden soll.
wenn ich die doku richtig verstanden habe, wird genau das nicht passieren, sieht so aus, als wenn es nur in kombination mit LIMIT geht.
Auf welche Aussage genau beziehst du dich da?
MfG ChrisB
Hello,
Auf welche Aussage genau beziehst du dich da?
vielleicht auf:
--
(SELECT a FROM tbl_name WHERE a=10 AND B=1 ORDER BY a LIMIT 10)
UNION
(SELECT a FROM tbl_name WHERE a=11 AND B=2 ORDER BY a LIMIT 10);
Das Einfügen von ORDER BY bei einzelnen SELECT-Anweisungen in Klammern hat nur in Kombination mit LIMIT Auswirkungen. Andernfalls wird ORDER BY wegoptimiert.
--
MfG
Rouven
yo,
Auf welche Aussage genau beziehst du dich da?
ich irre mich bezüglich den eigenheiten von mysql ja schon mal öfters, aber diese aussage bringt mich dazu.
"Das Einfügen von ORDER BY bei einzelnen SELECT-Anweisungen in Klammern hat nur in Kombination mit LIMIT Auswirkungen. Andernfalls wird ORDER BY wegoptimiert."
und ich musss gestehen, sie macht auch sind, weil sie damit nicht zur sortierung, sondern zur selektion eingesetzt wird.
Ilja
Hallo ChrisB,
bin leider noch nicht schlauer geworden. Wenn ich ein LIMIT innerhalb des UNION-Selects setze, verhindere ich aber, dass mir die Einträge nicht so ausgegeben werden wie gewünscht, oder?
Ich möchte ja zuerst ALLE Einträge geordnet nach Wunsch mit
top!=0 and color=0 and type=expert
dann ALLE Einträge geordnet nach Wunsch mit
top=0 and color!=0 and type=expert
dann ALLE Einträge geordnet nach Wunsch mit
top=0 and color=0 and type=expert
und ALLE Einträge geordnet nach Wunsch mit
type=basic
Mit einem LIMIT verhindere ich das doch, oder?
Außerdem möchte ich die gesamte Liste (also, den Result) über ein Limit beschränken... steh also noch ein wenig auf'n Schlauch.
Vllt. gibt es ja noch einen eleganteren Weg?
gondor(..)
Jemand eine Idee
Ja - RTFM :-)
MfG ChrisB
Hello,
Vllt. gibt es ja noch einen eleganteren Weg?
mehrere. Ich finde leider mein Posting zu deiner Ausgangsfrage nicht mehr, ich hatte dir dort neben UNION noch eine Lösung mit CASE vorgestellt, die deinen Bedürfnissen jetzt wahrscheinlich eher entsprechen würde.
bin leider noch nicht schlauer geworden. Wenn ich ein LIMIT innerhalb des UNION-Selects setze, verhindere ich aber, dass mir die Einträge nicht so ausgegeben werden wie gewünscht, oder?
jetzt musst du mir nochmal verraten was du möchtest - ich verstehe dich so, dass es diese "4 Kategorien" von Treffern gibt, die du mit einer gewissen Priorität selektieren möchtest. Über alle Treffer möchtest du eine Sortierung laufen lassen? Oder innerhalb der Gruppen? Am Ende sollen es maximal 100 Treffer werden?!
Was hindert dich daran, das LIMIT mit in die SELECTs zu setzen, du weißt, dass am Ende maximal 100 Treffer übrig bleiben, im Worst Case liefert also ein einzelnes Subselect alle 100 Treffer. Na gut, dann lass halt jedes Subselect selbst auch mit LIMIT 100 arbeiten. Das Ergebnis der 4 Unions sind dann maximal 400 Treffer, nach deinen Wünschen sortiert, von denen du dann per LIMIT 100 die ersten 100 herausgreifst.
(SELECT .. FROM .. ORDER BY ..LIMIT 100)
UNION
...
LIMIT 100
MfG
Rouven
jetzt musst du mir nochmal verraten was du möchtest - ich verstehe dich so, dass es diese "4 Kategorien" von Treffern gibt, die du mit einer gewissen Priorität selektieren möchtest. Über alle Treffer möchtest du eine Sortierung laufen lassen? Oder innerhalb der Gruppen? Am Ende sollen es maximal 100 Treffer werden?!
Was hindert dich daran, das LIMIT mit in die SELECTs zu setzen, du weißt, dass am Ende maximal 100 Treffer übrig bleiben, im Worst Case liefert also ein einzelnes Subselect alle 100 Treffer. Na gut, dann lass halt jedes Subselect selbst auch mit LIMIT 100 arbeiten. Das Ergebnis der 4 Unions sind dann maximal 400 Treffer, nach deinen Wünschen sortiert, von denen du dann per LIMIT 100 die ersten 100 herausgreifst.
(SELECT .. FROM .. ORDER BY ..LIMIT 100)
UNION
...
LIMIT 100
Hallo Rouven,
das kann ich machen, habe jedoch im Falle einer Seitennavigation ein gefälschtes Ergebnis. Das Limit müsste aus den einzelnen Selects raus und nur am Ende stehen.
dass es diese "4 Kategorien" von Treffern gibt, die du mit einer gewissen Priorität selektieren möchtest.
Über alle Treffer möchtest du eine Sortierung laufen lassen?
Oder innerhalb der Gruppen?
Am Ende sollen es maximal 100 Treffer werden?!
Du hattest mit diesen Ansatz gegeben:
(2) künstliches Einbringen einer Sortierspalte
SELECT id,
top,
color,
type,
CASE
WHEN (top != 0 AND color = 0 AND status='expert') THEN 1
WHEN (top=0 AND color!=0 AND status = 'expert') THEN 2
...
END AS sortierung
FROM tabelle
ORDER BY sortierung
Gruß,
gondor(..)
Hello,
Oder innerhalb der Gruppen?
- ja
was hindert dich dann darin, ORDER BY und LIMIT innerhalb des Subselect anzubringen - das Order By greift.
- nicht unbedingt. Ich möchtte eigentlich alle Treffer und diese Menge durch ein Limit beschränken.
genau, und wenn du weißt, dass du auf maximal X Treffer beschränken wirst, dann ist es ja auch kein Problem, wenn jedes Subselect schon maximal X Treffer liefert (anstatt alle) - oder klär mich auf, wo ich dich falsch verstehe.
Du hattest mit diesen Ansatz gegeben:
d.h. wenn du hier erst nach Sortierspalte und dann nach Datum sortierst und eine LIMIT 100 platzierst, dann müsste es auf das selbe rauskommen wie meine obige Ausführung.
MfG
Rouven
Hello,
Moin moin ;-)
Oder innerhalb der Gruppen?
- ja
was hindert dich dann darin, ORDER BY und LIMIT innerhalb des Subselect anzubringen - das Order By greift.
- nicht unbedingt. Ich möchtte eigentlich alle Treffer und diese Menge durch ein Limit beschränken.
genau, und wenn du weißt, dass du auf maximal X Treffer beschränken wirst, dann ist es ja auch kein Problem, wenn jedes Subselect schon maximal X Treffer liefert (anstatt alle) - oder klär mich auf, wo ich dich falsch verstehe.
Okay, wenn ich die Einträge ohne ein Limit auslese ist das kein Problem. Möchte ich jedoch die Einträge über eine Seitennavigation steuern, würde das Ergebnis doch verfälscht ausgegeben werden oder:
z.b.
Seite 1 Limit 0, 10
alle Top und expert (3 Einträge)
alle Color und expert (6 Einträge)
alle !Top und !Color und expert (1 Eintrag)
Seite 2 Limit 10, 10
restlichen !Top und !Color und expert (4 Eintrag)
alle basic (6 Einträge)
Seite 3 Limit 20, 10
alle basic (10 Einträge)
usw...
Erzwingt das Limit in den Select-Anweisungen nicht, das auf der 3. Seite z.b. wieder Top-Einträge gelistet werden? Wenn z.b. für Seite 3 in jeder Anweisung Limit 20, 10 steht kommen doch erst wieder alle Top, dann Color, usw... anstatt nur die basic zu liefern, da auf den vorderen Seiten die Einträge doch schon 'abgefrühstückt' wurden.
Oder habe ich hier ein Verständnisproblem?
Du hattest mit diesen Ansatz gegeben:
d.h. wenn du hier erst nach Sortierspalte und dann nach Datum sortierst und eine LIMIT 100 platzierst, dann müsste es auf das selbe rauskommen wie meine obige Ausführung.
Hmm... laut Test funktioniert diese Anweisung nicht wie gewünscht.
MfG
Rouven
Problem verstanden?
gondor(..)
Hello,
Seite 1 Limit 0, 10
Seite 2 Limit 10, 10
mein Hirn leidet noch unter einer zu langen Superbowlnacht, aber das klingt in der Tat erstmal nach einem Problem, weil du auf der Folgeseite wissen müsstest, welche Sätze auf Seite 1 zu sehen waren.
Hmm... laut Test funktioniert diese Anweisung nicht wie gewünscht.
wie sieht sie jetzt aus und was heißt das?
MfG
Rouven
yo,
mein Hirn leidet noch unter einer zu langen Superbowlnacht
habe ich auch live gesehen, war am ende sehr gut und spannend, habe ja den Cardinals die daumen gedrückt....
Ilja
Hello,
habe ich auch live gesehen, war am ende sehr gut und spannend, habe ja den Cardinals die daumen gedrückt....
jo, fand ich auch - am Anfang des vierten Quarters habe ich ernsthaft mal gedacht es wäre rum, zu großer Abstand, aber dann ging es doch alles irgendwie ziemlich schnell, hätte ich nicht gedacht...hat sich auf jeden Fall gelohnt.
MfG
Rouven
jo, fand ich auch - am Anfang des vierten Quarters habe ich ernsthaft mal gedacht es wäre rum, zu großer Abstand, aber dann ging es doch alles irgendwie ziemlich schnell, hätte ich nicht gedacht...hat sich auf jeden Fall gelohnt.
jep, am ende war noch mal richtig dynamik drinn. ich hätte es ja dem alten mann gegönnt. schade das es die interception am ende der ersten hälte gab, sonst hätten sie es gepackt.
Ilja
Hello,
jep, am ende war noch mal richtig dynamik drinn. ich hätte es ja dem alten mann gegönnt. schade das es die interception am ende der ersten hälte gab, sonst hätten sie es gepackt.
die interception war sowieso eine aus der kategorie "gibts nicht", sich da so die butter vom brot nehmen zu lassen...wobei roethlisberger schon vorher ein paar mal mehr fällig gewesen wäre, ich erinnere mich da an einen pass, den er geworfen hat, nachdem er eigentlich schon gestolpert und halb getacklelt wurde. sowas machts dann halt schwer.
und ganz ehrlich, solange es sich die cardinals leisten beim Fieldgoal den Ballhalter umzulaufen - na ja, immerhin haben sie die nächsten drei downs abgewehrt...
MfG
Rouven
Hi,
Erst kommen die Einträge mit...
- alle top!=0 AND color=0 und status=expert
- alle top=0 AND color!=0 und status=expert
- alle top=0 AND color=0 und status=expert
- alle status=basic
Ich würde das ohne UNION lösen.
Du willst alle mit "(color=0 or top=0) and status=expert) or status=basic".
Leider funktioniert das nicht, da die Einträge nicht wie gewollt nach Datum (oder was anderem) sortiert werden...
Jemand eine Idee, wieso?
Die Sortierung müsstest du soweit ich weiß erst nach der Verknüfung, also da wo LIMIT steht, machen.
Aber das UNION wird hier ja eh nicht gebraucht.
mfG,
steckl