Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Datenbanken (https://www.delphipraxis.net/15-datenbanken/)
-   -   Zum nächsten Datensatz springen (https://www.delphipraxis.net/151967-zum-naechsten-datensatz-springen.html)

Luckie 8. Jun 2010 01:01

Datenbank: MySQL • Version: ? • Zugriff über: PHP

Zum nächsten Datensatz springen
 
Ich versuche gerade mit einem SQL-Statement die ID des nächsten Datensatzes zu bekommen:
Code:
function getNextID($id) {
      $query = "SELECT * FROM adressen
               WHERE
                  (gesch_firma > ( SELECT gesch_firma FROM adressen WHERE id = $id ))
               OR
                  (name > ( SELECT name FROM adressen WHERE id = $id ))               
               OR
                  (vorname > ( SELECT vorname FROM adressen WHERE id = $id ))
               ORDER BY gesch_firma, name, vorname ASC limit 0,1";
      $resPrev = mysql_query ($query);
      $prevID = mysql_fetch_object($resPrev);      
      return $prevID->id;
   }
(OK, das drumherum ist PHP, aber das ist egal.)
Allerdings springt er mir so nur zwischen zwei Datensätzen hin und her. Zu beachten ist, dass nicht immer alle Felder (gesch_firma, name, vorname) einen Wert haben, also leer sein können. Dann sollen die Datensätze der Reihenfolge gesch_firma, name, vorname durchgeblättert werden, so wie sie auch sortiert sind.

Als Vorlage diente mir diese Seite: http://webdesign.tepelmann.com/index...Datensatz.html Aber wenn ich das nur auf das Feld namen beschränke, überspringt er Datensätze.

H4ndy 8. Jun 2010 04:01

AW: Zum nächsten Datensatz springen
 
Ich glaube der verrammelt da was mit der Oder-Verknuepfung.
Trenne das mal in 3 einzelne Abfragen auf und implementiere die Logik selbst
if ($idFirma != "") { $prevID = $idFirma } else { usw.

DeddyH 8. Jun 2010 08:39

AW: Zum nächsten Datensatz springen
 
Ich denke, mit Aggregatfunktionen käme man weiter.
SQL-Code:
SELECT MIN(ID)
FROM Tabelle
WHERE ID > :aktuelle_ID

mkinzler 8. Jun 2010 08:48

AW: Zum nächsten Datensatz springen
 
Oder mit Limitierung

SQL-Code:
SELECT
   TOP 1 ID
FROM
    Tabelle
WHERE
    ID > :aktuelle_ID;

DeddyH 8. Jun 2010 09:44

AW: Zum nächsten Datensatz springen
 
Aber dann müsstest Du zur Sicherheit noch nach ID sortieren, wenn ich gerade keinen Denkfehler mache.

mkinzler 8. Jun 2010 09:53

AW: Zum nächsten Datensatz springen
 
Wer zur Sicherheit besser, obwohl es bei der Id auch so stimmen sollte

idefix2 8. Jun 2010 10:18

AW: Zum nächsten Datensatz springen
 
Delphi-Quellcode:
      $query = "SELECT * FROM adressen
               WHERE
                  (gesch_firma > ( SELECT gesch_firma FROM adressen WHERE id = $id ))
               OR
                  (name > ( SELECT name FROM adressen WHERE id = $id ))              
               OR
                  (vorname > ( SELECT vorname FROM adressen WHERE id = $id ))
               ORDER BY gesch_firma, name, vorname ASC limit 0,1";
So kann das nicht gut gehen:

der 1. Teil des where liefert alle Datensätze, in denen gesch_firma grösser als im aktuellen Datensatz ist.
der 2. Teil liefert ALLE Datensätze, in denen name grösser als im aktuellen Datensatz ist, aber natürlich auch jene, in denen gesch_firma kleiner als im aktuellen Datensatz ist.
Im 3. Teil werden dann noch ALLE Datensätze geliefertt, bei denen der Vorname grösser ist. Damit erhältst du aber eine Menge Sätze, die laut aktueller Sortierfolge vor dem aktuellen Datensatz liegen.

Prinzipiell müsste eine Bedingung bei drei Sortierkriterien a,b und c in etwa so aussehen:

where (a>a0) or ((a=a0) and (b>b0)) or ((a=a0) and (b=b0) and (c>c0))

Zitat:

Zu beachten ist, dass nicht immer alle Felder (gesch_firma, name, vorname) einen Wert haben, also leer sein können.
Wenn Du damit meinst, dass der Wert ein leerer String sein kann, dann ist es egal. Der leere String liegt in der Sortierfolge vor jedem anderen String. Wenn allerdings Werte NULL sein können, wird es wesentlich komplizierter, weil das Ergebnis jedes Vergleichs, in den der Wert NULL involviert ist, als Ergebnis wieder NULL liefert.

Luckie 8. Jun 2010 10:57

AW: Zum nächsten Datensatz springen
 
Zitat:

Zitat von idefix2 (Beitrag 1026756)
Damit erhältst du aber eine Menge Sätze, die laut aktueller Sortierfolge vor dem aktuellen Datensatz liegen.

Deswegen limitiere ich das ja auf einen Datensatz.

[/quote]Prinzipiell müsste eine Bedingung bei drei Sortierkriterien a,b und c in etwa so aussehen:

where (a>a0) or ((a=a0) and (b>b0)) or ((a=a0) and (b=b0) and (c>c0))[/quote]
Aber a0, b0 und c0 habe ich ja nicht.

Zitat:

Wenn Du damit meinst, dass der Wert ein leerer String sein kann, dann ist es egal. Der leere String liegt in der Sortierfolge vor jedem anderen String. Wenn allerdings Werte NULL sein können, wird es wesentlich komplizierter, weil das Ergebnis jedes Vergleichs, in den der Wert NULL involviert ist, als Ergebnis wieder NULL liefert.
Nein, nur Leerstrings.

idefix2 8. Jun 2010 11:05

AW: Zum nächsten Datensatz springen
 
Zitat:

Deswegen limitiere ich das ja auf einen Datensatz.
Es genügt, wenn der eine Datensatz in der Sortierfolge vor dem aktuellen liegt, damit der ganze Algorithmus nicht funktioniert.


Code:
  $query = "SELECT * FROM adressen
               WHERE
                  (gesch_firma > ( SELECT gesch_firma FROM adressen WHERE id = $id ))
               OR
                  ((gesch_firma = ( SELECT gesch_firma FROM adressen WHERE id = $id ))
                    and
                   (name > ( SELECT name FROM adressen WHERE id = $id )))
               OR
                  ((gesch_firma = ( SELECT gesch_firma FROM adressen WHERE id = $id ))
                    and
                   (name = ( SELECT name FROM adressen WHERE id = $id ))
                    and
                   (vorname > ( SELECT vorname FROM adressen WHERE id = $id )))
               ORDER BY gesch_firma, name, vorname ASC limit 0,1";

DeddyH 8. Jun 2010 11:16

AW: Zum nächsten Datensatz springen
 
Es ist übrigens Quatsch, alle Felder abzufragen, wenn man nur die ID braucht.

idefix2 8. Jun 2010 11:19

AW: Zum nächsten Datensatz springen
 
Ich nehme an, er braucht dann nicht nur die id, sondern den ganzen nächsten Datensatz. Den will er ja anzeigen.

DeddyH 8. Jun 2010 11:21

AW: Zum nächsten Datensatz springen
 
Zitat:

Code:
return $prevID->id;

Nö, nur die ID. Also kauft er für ein Glas Milch gleich eine ganze Kuh :mrgreen:

Luckie 8. Jun 2010 11:28

AW: Zum nächsten Datensatz springen
 
Ja, ich brauche nur die ID. Aber Optimierung kommt später. Erst mal soll es überhaupt funktionieren.

@Idefix: Ich werde deine Lösung nachher mal ausprobieren.

Luckie 8. Jun 2010 17:08

AW: Zum nächsten Datensatz springen
 
@Idefix: Jetzt geht er aber nur die Datensätze durch, bei denen das Feld gesch_firma nicht leer ist. Aber ich brauche natürlich auch alle anderen, also bei denen gesch_firma oder name oder vorname leer ist.

DeddyH 8. Jun 2010 18:52

AW: Zum nächsten Datensatz springen
 
Wie sieht es so aus?
SQL-Code:
SELECT
  ID
FROM
  adressen
WHERE
  CONCAT_WS(' ',gesch_firma,name,vorname) >=
    (SELECT
       CONCAT_WS(' ',gesch_firma,name,vorname)
     FROM
       adressen
     WHERE ID = $id)
AND
  ID <> $id
ORDER BY
  gesch_firma,name,vorname
LIMIT 1

idefix2 8. Jun 2010 19:30

AW: Zum nächsten Datensatz springen
 
Das klingt sehr danach, als wären doch NULLs im Spiel (dann wird übrigens die von DeddyH vorgeschlagene Abfrage das gleiche Ergebnis liefern). Der normale Leerstring wird im Vergleich kleiner als jeder andere String gereiht und ganz normal verglichen - für den Algorithmus macht also ein Leerstring keinen Unterschied. Die Datensätze, bei denen gesch_firma den Leerstring enthalten, müssten als erste angezeigt werden.

Wenn allerdings ein Feld NULL enthält, ergibt jeder Vergleich mit dem Feld ebenfalls NULL, was zur Folge hat, dass die Query keine Datensätze liefert, bei denen auch nur eines der drei Felder NULL ist.

Ich versuche, in meinen Datenbanken NULL wo immer es geht zu vermeiden, weil dieser Wert das ganze Handling (meistens unnötig) kompliziert.

edit: Die Abfrage aus Post 15 würde durch das ">=" eine Endlosschleife produzieren, wenn in der DB zwei Datensätze liegen, bei denen das concat der drei Felder gesch_firma, name und vorname den selben Wert ergibt, z.B. Firma Maier mit Leerstring als Name und Vorname und Person Maier mit Leerstring als gesch_firma und vorname.

edit 2: Ich habe eben geschrieben "was zur Folge hat, dass die Query keine Datensätze liefert, bei denen auch nur eines der drei Felder NULL ist." Das stimmt so aber nicht ganz, weil zwar fast alle Operationen, in die ein NULL-Wert involviert ist, wieder NULL ergeben, es gibt aber glaube ich zwei Ausnahmen: (NULL and false) liefert false, (NULL or true) liefert true.

DeddyH 8. Jun 2010 20:22

AW: Zum nächsten Datensatz springen
 
Ich habe noch nie gehört, dass ein SQL-Statement ein Endlosschleife ergeben soll :gruebel:

Luckie 8. Jun 2010 20:24

AW: Zum nächsten Datensatz springen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also NULL kann keines der Felder werden. Siehe Anhang.


Ich werde das von DeddyH mal probieren. Was macht den CONCAT_WS? das kenne ich nicht.

Hm, das liefert gar keine ID.

mkinzler 8. Jun 2010 20:25

AW: Zum nächsten Datensatz springen
 
Es hängt mehrere Felder zusammen und fügt ein Trennzeichen dazwischen ein

DeddyH 8. Jun 2010 20:27

AW: Zum nächsten Datensatz springen
 
CONCAT_WS hängt die Strings ab Parameter 2 hintereinander, verwendet aber den 1. Parameter als Trenner.

Luckie 8. Jun 2010 20:30

AW: Zum nächsten Datensatz springen
 
Nein, wie gesagt, da bekomme ich eine leere ID zurück. Dann werde ich es doch wohl so machen wie himitsu es vorgeschlagen hat und es einzeln machen müssen.

DeddyH 8. Jun 2010 20:34

AW: Zum nächsten Datensatz springen
 
Wo hat himitsu was vorgeschlagen? Und hast Du das mal mit verschiedenen IDs versucht, es ist ja immerhin möglich, dass Du zufällig den letzten DS in der Sortierfolge erwischt hast.

Luckie 8. Jun 2010 20:44

AW: Zum nächsten Datensatz springen
 
Oh, es war H4ndy.

Ja, ich habe es mit verschiedenen Datensätzen ausprobiert.

DeddyH 8. Jun 2010 20:46

AW: Zum nächsten Datensatz springen
 
Dann muss ich aber einen dicken Denkfehler in meiner Logik gemacht haben :gruebel:

Luckie 8. Jun 2010 20:50

AW: Zum nächsten Datensatz springen
 
Ich bin in SQL auch nicht so fit und da haben mir die SQL-Statements schon ziemliche Kopfschmerzen bereitet. Aber es kann doch nicht sein, dass ich der erste bin, der so eine Datensatz-Durchblätter-Funktion haben will. ;)

mkinzler 8. Jun 2010 20:53

AW: Zum nächsten Datensatz springen
 
Warum verwendest du dann nicht einfach LIMIT?

DeddyH 8. Jun 2010 21:00

AW: Zum nächsten Datensatz springen
 
Nur zur Kontrolle, ob ich die Anforderung richtig interpretiert habe: angenommen, Du hast die Abfrage
SQL-Code:
SELECT
  ID, Firma, Name, Vorname
FROM
  Tabelle
ORDER BY
  Firma, Name, Vorname
Dabei kommt dann so etwas heraus:
Code:
42    Meier GmbH   Meier  Alfred
1337  Meier GmbH   Meier  Boris
4711  Müller GbR          Anton
Nun möchtest Du, dass bei ID-Parameter 1337 die ID 4711 herauskommt, stimmt das soweit?

Luckie 8. Jun 2010 21:12

AW: Zum nächsten Datensatz springen
 
Richtig. Es können aber auch Datensätze mit leerer Firma und/oder leerem Namen und/oder leerem Vornamen rauskommen. Wobei mindestens eins von den drei Felder belegt ist (sonst macht der Datensatz keinen Sinn). Zum Beispiel bei privaten Kontakten ist Firma leer und Name und Vorname belegt, wobei Name muss auch nicht unbedingt belegt sein in so einem Fall.

mkinzler 8. Jun 2010 21:14

AW: Zum nächsten Datensatz springen
 
Dann sollte LIMIT aber greifen

Luckie 8. Jun 2010 21:15

AW: Zum nächsten Datensatz springen
 
Wie meinst du das? Gib doch mal bitte das komplette SQL-Statement an, was du meinst.

DeddyH 8. Jun 2010 21:16

AW: Zum nächsten Datensatz springen
 
Setz doch bitte mal zur Kontrolle folgendes Statement ab:
SQL-Code:
SELECT
  CONCAT_WS(' ',gesch_firma,name,vorname)
FROM
  adressen
ORDER BY
  1
Kommt da ein Ergebnis? Ich habe hier leider kein MySQL verfügbar.

Luckie 8. Jun 2010 21:20

AW: Zum nächsten Datensatz springen
 
Ergebnis sind alle Datensätze sortiert. Zu erst die mit leerer Firma und Name, also nur mit Vornamen, dann alle mit Namen und Vornamen und dann alle mit Firma alphabetisch nach Firma.

mkinzler 8. Jun 2010 21:20

AW: Zum nächsten Datensatz springen
 
SQL-Code:
Select
    <Feldliste>
from
    <Tabelle>
order by
    CONACT_WS( ' ', ...)
limit
    <Offset>, <Anzahl>;

DeddyH 8. Jun 2010 21:22

AW: Zum nächsten Datensatz springen
 
Markus, das Problem ist, dass er den Offset nicht kennt.

mkinzler 8. Jun 2010 21:24

AW: Zum nächsten Datensatz springen
 
Wenn er Pagination will kennt er die doch
0, Anzahl_pro_Sete, 2*Anzahl_pro_Seite, ...

Luckie 8. Jun 2010 21:26

AW: Zum nächsten Datensatz springen
 
Äh doch. Die aktuelle Datensatz ID kenne ich. Siehe meinen ersten Beitrag. Oder was meinst du mit Offset?

Nein keine Pagination, die habe ich schon. Ich will jeden einzelnen Datensatz nacheinander durchblättern können.

DeddyH 8. Jun 2010 21:29

AW: Zum nächsten Datensatz springen
 
Aber Du weißt doch nicht, an welcher Stelle der Datensatz mit der ID X steht, oder hab ich einen Knoten im Hirn?

Luckie 8. Jun 2010 21:31

AW: Zum nächsten Datensatz springen
 
Nein, das weiß ich natürlich nicht.

mkinzler 8. Jun 2010 21:33

AW: Zum nächsten Datensatz springen
 
Vielleicht könnte man mit einer Derived Table etwas erreichen. Erst Menge in Reihenfolge bringen, DS bis einschlieeslich ID "ausblenden" ( ... where ...)

DeddyH 8. Jun 2010 21:33

AW: Zum nächsten Datensatz springen
 
Na also, wenn ich LIMIT nicht völlig falsch verstanden habe richtet das sich nach der aktuellen Sortierreihenfolge. Btw suche ich immer noch meinen Denkfehler :gruebel:

[edit] Dröseln wir das mal gemeinsam auf.
SQL-Code:
SELECT
  ID
FROM
  adressen
WHERE
  CONCAT_WS(' ',gesch_firma,name,vorname) >=
    (SELECT
       CONCAT_WS(' ',gesch_firma,name,vorname)
     FROM
       adressen
     WHERE ID = $id)
AND
  ID <> $id
ORDER BY
  gesch_firma,name,vorname
LIMIT 1
Ich suche alle DS, die im angegebenen Format ein gleiches oder größeres Ergebnis aufweisen. Von diesen möchte ich nur die, deren ID von der gesuchten abweicht. Und von denen wiederum interessiert uns nur der Erste. So war es gedacht, sieht jemand, was ich nicht sehe?[/edit]


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:56 Uhr.
Seite 1 von 2  1 2      

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