| | | | |
| |||||||
| Datenbanken SQL und Co |
|
| | LinkBack | Themen-Optionen | Thema bewerten |
| | |
| PHP Code Flüsterer Registriert seit: 21.08.2005 Beiträge: 4682 PHP-Kenntnisse: Fortgeschritten | |
| | ||
| Gast
Beiträge: n/a
| Zitat:
Hier eine mögliche Lösung mit einem SQL, wobei diese versagt, wenn zwei Datensätze eine identische "time" haben. Dann werden mehrere Vorgänger/Nachfolger ausgegeben. In dem SUB-Select werden die drei Kandidaten ermittelt. Code: SELECT * FROM data
WHERE time IN (
SELECT MIN(time) FROM data
WHERE time > ( SELECT time FROM data
WHERE id = 4 )
UNION ALL
SELECT time FROM data
WHERE id = 4
UNION ALL
SELECT MAX(time) FROM data
WHERE time < ( SELECT time FROM data
WHERE id = 4 )
)
ORDER BY time;
+----+-------+---------------------+
| id | group | time |
+----+-------+---------------------+
| 3 | 1 | 2010-03-01 07:23:00 |
| 4 | 1 | 2010-04-01 09:47:00 |
| 5 | 1 | 2010-04-03 02:01:00 |
+----+-------+---------------------+
3 rows in set (0.02 sec)
mysql>
Thomas | |
|
| | |
| Erfahrener Benutzer Registriert seit: 04.07.2003
Beiträge: 359
PHP-Kenntnisse: Fortgeschritten ![]() | Ich weiß, dass UNION und Sub-Selects möglich sind, aber führt das immer zu einem neuen Select und damit doch auch zu einer neuen (internen) Abfrage, oder? @ChrisB: Okay, das mit dem * war eig nur für eine kurze Schreibsweise des ganzen gewählt, wo ich eig wirklich nur wenige Felder des Vorgängers und Nachfolgers benötige. Ich habe damals anstatt dem Feld time ein Feld order gehabt, mit einer laufenden Nummer und konnte dann folgende Abfrage ausführen: Code: SELECT d.id, d.time, d1.id as privid, d2.id as nextid
FROM `data` as d
LEFT OUTER JOIN `data` as d1
ON d1.order = d.order - 1
LEFT OUTER JOIN `data` as d2
ON d2.order = d.order + 1
WHERE d.id = 4;
@thomas_w: Sind das dann aber nicht vier Sub-Selects pro Datensatz und daher schlechter optimiert als die zwei einzelnen Abfragen/Sub-Selects pro Datensatz? |
| | |
| | ||
| Gast
Beiträge: n/a
| Zitat:
Für mein Beispiel (siehe #5) wären folgender Index sinnvoll: Code: CREATE INDEX sx_data_01 ON data (time, id); Bei timestamp geht ein "-1" und "+1" nicht, deshalb ja die MIN(), MAX() Aggregationen, um den Vorgänger bzw. Nachfolger zu finden. Die SUB-Query greifen direkt auf den Index zu, dass sollte schnell gehen, aber bestimmt gibt es auch andere Lösungen für das Problem. Grüße Thomas Geändert von thomas_w (28.04.2010 um 13:07 Uhr). Grund: siehe #5 | |
|
| | |
| moderatives Dielektrikum Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | Von lückenlosen IDs auszugehen, davon kann man nur immer wieder abraten. Auch eine inkrementierende Hilfsvariable ist eher unrealisitisch auf lange Sicht zu pflegen. Welchen Hintergrund hat denn die Anwendung? Was wird da verwaltet und dargestellt?
__________________ -- One pixel is still too big. Please make it smaller. ASAP. Initiative Mittelstand. Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers. -- |
| | |
| | |||
| Erfahrener Benutzer Registriert seit: 04.07.2003
Beiträge: 359
PHP-Kenntnisse: Fortgeschritten ![]() | Zitat:
Ich verwende jetzt folgende Abfrage mit zwei Sub-Selects, welche wunderbar funktioniert und mit meiner (noch) recht kleinen Tabelle (zZt ~500 Einträge) noch gute Zeiten hinlegt: Code: SELECT d.id, (
SELECT d1.id
FROM `data` AS d1
WHERE d1.time < d.time
AND d1.group = d.group
ORDER BY d1.time DESC
LIMIT 1
) AS privid, (
SELECT d2.id
FROM `data` AS d2
WHERE d2.time > d.time
AND d2.group = d.group
ORDER BY d2.time ASC
LIMIT 1
) AS nextid
FROM `data` AS d
Zitat:
Noch eine kleine Frage zum Sub-Select, dann mache ich das Thema dicht, weil der Query soweit gut funktioniert, auch wenn die Tabellengröße evtl iwann das Thema wieder aktuell werden lassen könnte: Kann ich von einem Sub-Select auch mehr als ein Wert zurückgeben lassen, so wie in etwa in einer solchen Abfrage (ähnlich wie bei dem Befehl list() von PHP): Code: SELECT d.id, (
SELECT d1.id, d1.time <<-- HIER
FROM `data` AS d1
WHERE d1.time < d.time
AND d1.group = d.group
ORDER BY d1.time DESC
LIMIT 1
) AS ( privid, privtime) <<-- HIER
FROM `data` AS d
| ||
| | |
| | |
| moderatives Dielektrikum Registriert seit: 21.05.2008
Beiträge: 35.987
PHP-Kenntnisse: Fortgeschritten ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() ![]() | Das verstehst Du falsch. Das AS bildet den ALias für die Subselectergebnistabelle, die Du im äußeren Select darüber ansprechen kannst. Die Feldangaben am ersten HIER werden nach außen durchgereicht, außer sie kollidieren mit Datenfeldern des äußeren Select, dann solltest Du auch dafür Aliase verwenden.
__________________ -- One pixel is still too big. Please make it smaller. ASAP. Initiative Mittelstand. Die wichtigste Gestaltungsregel im Screendesign ist Pi mal Daumen des Arbeitgebers. -- |
| | |
|
| Themen-Optionen | |
| Thema bewerten | |
|
|
Ähnliche Themen | ||||
| Thema | Autor | Forum | Antworten | Letzter Beitrag |
| result Variablen von SQL verbinden | vci | PHP Tipps 2010 | 15 | 05.02.2010 19:09 |
| SELECT WHERE datetime abfrage - Optimierung | mrSpok | Datenbanken | 15 | 23.03.2006 19:08 |
| Besucher kamen über folgende Suchanfragen bei Google auf diese Seite |
| sql vorgänger nachfolger, sql vorgänger, vorgänger nachfolger sql, sql vorgänger und nachfolger, vorgänger nachfolger deutsch, vorgänger und nachfolger deutsch, sql abfrage vorgänger datensatz, vorgänger sql, sql suchen vorgänger, php forum vorgaenger, sql vorgänger nachfolger bestimmen, sql datensatz suchen nachfolger, sql vorgänger finden, \transact sql\ |t-sql vorgänger datensatz ermitteln, mysql select vorgänger nachfolger, sql vorgänger datensatz ermitteln, php nachfolger, mysql vorgänger nachfolger, vorgänger und nachfolger, mysql vorgänger und nachfolger |