PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Ergebnismenge mittig selektieren.


Indyk
12.06.2009, 07:50:10
Hallo Freunde der relationalen Datenbanken. Entschuldigt den schwammigen Titel , wie so oft ist mir kein passenderer eingefallen.

Ich möchte einen Usemenge anhand der Punkte von user x selektieren. Der Knackpunkt an dem ich nicht vorbei komme ist, die es sollen die nächsten 10 user mit höherer punkte zahl als user x sein , und es sollen die nächsten 10 user mit niedriger punkte zahl als user x sein.

Mein erster versuch ging gleich mit UNION

SELECT
*
FROM
user
WHERE
punkte > (SELECT punkte FROM user where id = 1)
LIMIT 0,10

UNION

SELECT
*
FROM
user
WHERE
punkte < (SELECT punkte FROM user WHERE id = 1)
LIMIT 0,10


Bei diesem statement habe ich 2 Probleme:
a) die statements müssen unterschiedlich sortiert werden was mit UNION (sofern ich die doku richtig verstanden habe) nicht funktioniert
b) wenn ich das statement ausführe bekomme ich nur eine Ergebnismenge zurück, hattees aber nur einmal kurz in phpmyadmin getestet

Es wäre ja auch einfach mit BETWEEN -10000 punkte und +10000 punkte, aber das ist ja gut möglich das sich niemand in diesem spektrum aufhält und die ergebnismenge ist dann leer.

Falls jetzt ein geschultes auge sagt das geht nicht ohne weiteres (z.B. nur mit einer prozedur) dann bin ich auch gewillt 2 statements abzuschicken ( ;

Ich hab auch schon (für mich) abenteuerliche statements gesehen wo sich tabellen selbst joinen, vll. gehört das ja zu diesen anwendungsfall?

update
Evtl. tritt diese problematik so häufig auf das es ein gescheiten namen dafür gibt? Evtl. würde der mir ja schon helfen wenn ich dadurch andere problemlösungen finden würde.

Indyk
16.06.2009, 09:29:57
Nach ein bisschen Recherche wurde mir klar das Klammern wahre wundern bewirken kann. so kam ich dann auch zu meiner Lösung:

SELECT *
FROM
(
(
SELECT *
FROM user
WHERE punkte >
(
SELECT punkte
FROM user
WHERE id =1
)
ORDER BY punkte
LIMIT 0 , 10
)
UNION
(
SELECT *
FROM user
WHERE punkte <
(
SELECT punkte
FROM user
WHERE id =1
)
ORDER BY punkte DESC
LIMIT 0 , 10
)
) AS temp
ORDER BY punkte DESC


Wenn jemand einen anderen vorschlag hat, bin ich ganz Ohr.

Crisps
16.06.2009, 15:21:55
Ich weiß jetzt auf die schnelle nicht ob es einen anderen oder besseren Weg gibt, allerdings kannst Du in deinem Beispiel auf:

SELECT *
FROM
(
und
) AS temp
verzichten.

Indyk
16.06.2009, 15:28:55
Indeed, so geht es auch:

(
SELECT *
FROM user
WHERE punkte >
(
SELECT punkte
FROM user
WHERE id =1
)
ORDER BY punkte
LIMIT 0 , 10
)
UNION
(
SELECT *
FROM user
WHERE punkte <
(
SELECT punkte
FROM user
WHERE id =1
)
ORDER BY punkte DESC
LIMIT 0 , 10
)
ORDER BY punkte DESC


danke für den Tipp