Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   [SQL] Datensatz + vorigen/nächsten ermitteln (https://www.delphipraxis.net/98246-%5Bsql%5D-datensatz-vorigen-naechsten-ermitteln.html)

Matze 23. Aug 2007 20:46


[SQL] Datensatz + vorigen/nächsten ermitteln
 
Hallo,

ich möchte den Datensatz mit einer bestimmten ID ermitteln und die IDs des vorigen/nächsten Datensatzes. Bisher habe ich das so gelöst:

SQL-Code:
# aktuelle ID
SELECT id FROM tab WHERE id = MY_ID

# vorige ID
SELECT id FROM tab WHERE id < MY_ID ORDER BY id DESC LIMIT 1

# nächste ID
SELECT id FROM tab WHERE id > MY_ID ORDER BY id ASC LIMIT 1
Nun dachte ich mir, dass das sicher auch mit einem einzigen Query gehen müsste, nur weiß ich nicht, wie das aussehen könnte.

Geht das, wenn ja, wie muss das Query aussehen?


Grüße, Matze

mkinzler 23. Aug 2007 20:47

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Dann müsstest du die 3 Abfragen zusammenjoinen bzw. als Union zusammenfügen

Matze 23. Aug 2007 20:51

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Hallo Markus,

danke für deine Antwort. Per UNION könnte man natürlich sämtliche Queries zusammenfassen, das ist richtig, doch das ist eigentlich nicht Sinn der Sache und ich persönlich finde es unübersichtlicher und Vorteile hätte es auch keine. Ich dachte, dass es etwas gibt wie

SQL-Code:
SELECT id FROM tab
    WHERE id = MY_ID
        AND id = PREV(MY_ID)
        AND ID = NEXT(MY_ID)
Natürlich geht das so nicht, aber sowas habe ich mir erhofft, doch dann scheint das wohl nicht zu gehen. Mein Ziel sollte die Vereinfachung meines Codes sein bzw. eine kleine Verschönerung.

mkinzler 23. Aug 2007 21:00

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
So sollte es eigentlich gehen:
SQL-Code:
SELECT
    t1.id,
    (SELECT id FROM tab WHERE id < t1.id ORDER BY id DESC LIMIT 1 as vorgaenger,
    (SELECT id FROM tab WHERE id > t1.id ORDER BY id ASC LIMIT 1) as nachfolger
FROM
    tab t1 WHERE t1.id = MY_ID;

omata 23. Aug 2007 21:02

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Hallo Matze,

vielleicht so...
SQL-Code:
SELECT a.id, MAX(b.id) prior_id, MIN(c.id) next_id
FROM tab a
LEFT JOIN tab b
  ON a.id > b.id
LEFT JOIN tab c
  ON a.id < c.id
WHERE a.id = :id
GROUP BY a.id
Gruss
Thorsten

Matze 23. Aug 2007 21:08

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Hm danke euch, doch dann habe ich im Endeffekt wieder 3 Queries (Markus) oder eines, das ich 3 Mal durchlesen muss, um zu wissen, was es eigentlich macht (Thorsten). :mrgreen:

Ich glaube, dann bleibe ich bei den 3 Mini-Queries. Was so einfaches, wie ich's mir gewünscht habe, gibt's dann wohl nicht. Dennoch danke. :)

marabu 24. Aug 2007 06:49

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Guten Morgen Matthias,

mit Transact-SQL würde ich es so machen:

SQL-Code:
SELECT TOP 3 id
FROM tab
ORDER BY ABS(id - :id)
Das Prinzip lässt sich auf andere SQL-Dialekte anpassen.

Grüße vom marabu

Matze 24. Aug 2007 09:14

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Hallo marabu,

danke, doch habe ich es nicht hinbekommen, das für MySQL umzuschreiben. Meine Frage war auch mehr interessehalber und meine bisherigen Lösung klappt auch wunderbar. Sie ist eben etwas länger. Ich habe u.a. auch Queries, die sich über einige Zeilen ziehen und da dann so etwas verschachteltes zu nutzen, wie zu Beginn erwähnt wurde, wäre nicht mehr lesbar.

marabu 24. Aug 2007 09:27

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Hier der Code für MySQL - auch nur interessehalber:

SQL-Code:
SELECT id
FROM tab
ORDER BY ABS(id - :id)
LIMIT 3
Freundliche Grüße

mkinzler 24. Aug 2007 09:36

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Hallo Achim und was passiert wenn groessere Luecken in den IDs bestehen ?

marabu 24. Aug 2007 09:46

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Hi Markus,

das kommt auf die Größe der Lücke an.

An welche Größe denkst du jetzt so?

Fröhliche Grüße

mkinzler 24. Aug 2007 09:53

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Jetzt hast du den Code ja korrigiert.

marabu 24. Aug 2007 10:07

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Hallo Markus,

bezog sich deine Frage tatsächlich auf "Abs(id - 5)"?

Die Fünf stammt aus dem Testlauf auf meiner Maschine und steht gewiss nicht für eine Lückengröße. Sie ist der Schlüssel, der mit seinen Nachbarn zusammen zurückgeliefert werden soll. Ich habe die Fünf analog zu meinem ersten Beitrag durch einen Parameter ersetzt. Die lustigere Frage wäre wohl gewesen: "Was wenn der gesuchte Schlüssel einmal nicht 5 ist?"

Der Abstand der Schlüssel spielt übrigens keine Rolle. Wäre er definiert, dann wäre das Problem für Matthias wohl gar nicht erst entstanden.

Freundliche Grüße

joachimd 24. Aug 2007 14:47

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Zitat:

Zitat von marabu
SQL-Code:
SELECT TOP 3 id
FROM tab
ORDER BY ABS(id - :id)

geht nicht! Beispiel (zB entsteht so etwas, wenn ein paar Datensätze gelöscht werden):

SQL-Code:
create table #tmp(id integer);
insert into #tmp values(1);
insert into #tmp values(5);
insert into #tmp values(6);
insert into #tmp values(7);
insert into #tmp values(10);
insert into #tmp values(15);
insert into #tmp values(20);

select top 3 id from #tmp ORDER BY ABS(id - 5);
Ergebnis: 5,6,7 -> 1,5,6 ist aber gewünscht (weil Vorgänger und Nachfolger von 5 gesucht sind)

marabu 24. Aug 2007 17:16

Re: [SQL] Datensatz + vorigen/nächsten ermitteln
 
Hallo Joachim,

du hast Recht, der Ansatz über die Distanz führt zu einem falschen Ergebnis, wenn die beiden Abstände zu den Nachbarn nicht gleich groß sind. Entweder der Vorgänger oder der Nachfolger müssen exakt bestimmt werden, sodass sich eine Subquery nicht vermeiden lässt:

SQL-Code:
/* MYSQL Syntax, ungetestet */

SELECT id
FROM tab
WHERE id >= (
  SELECT MAX(id)
  FROM tab
  WHERE id < :id
)
ORDER BY id
LIMIT 3
Freundliche Grüße


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:36 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz