globe: Nur jeden x-ten Datensatz finden

n'abend,

Vorbedingungen:

* Wir sprechen von MySQL 5

* Datensätze haben fortlaufenden PrimaryKey. Da Datensätze aber gelöscht werden können (und für die aktuelle Abfrage ggf. nicht interessant sind) sind die IDs nicht wirklich fortlaufend, sondern "löchrig". Z.B. 1, 5, 6, 7, 23, 24, 100.

* Eine (generierte) Seite zeigt immer nur eine bestimmte Anzahl Datensätze (um zu vermeiden, dass eine Seite 12345123232 Einträge enthält...).

* Ein Datensatz weiss nicht auf welcher Seite er zu finden ist, da das ganze dynamisch berechnet wird. (Stichwort: "LIMIT 12, 34", wissenschon™)

Problemstellung:

Ermittle die Seite, auf der der Datensatz mit der ID %ID% zu finden ist.

Bisherige Lösung:

  1. Lade alle relevanten IDs (sortiert) => DBIDs
  2. Initialisiere Zähler := 0
  3. FOR %Y% IN DBIDs
    4-1) Erhöhe Zähler
    4-2) IF %Y% = %X% THEN RETURN CEILING( Zähler / DatensätzeProSeite )
    4-3) IF %Y% > %X% THEN RETURN Not-Found-till-page: CEILING( Zähler / DatensätzeProSeite )

Überlegung zur Optimierung:

Ist es möglich nur jeden X-ten Datensatz zu bekommen? Wenn ich weiss, dass jede Seite max. 15 Datensätze anzeigt, dürfte es mir doch genügen jede 15. ID zu bekommen, um einen Range-Vergleich zu machen. Das würde bedeuten, dass ich irgendwie mit einer Datenbank-internen Variable »CurrentRowNumber« arbeiten können müsste. Mir ist diesbezüglich aber nichts fundiertes bekannt.

Jemand ne bessere Idee?

weiterhin schönen abend...

--
Freundlich wie man war, hat man mir Großbuchstaben geschenkt.
sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
  1. Hallo globe,

    kannst du dir nicht einfach die Anzahl der Datensätze zurückgeben lassen, deren ID kleinergleich der des gesuchten ist und diese Zahl durch EinträgeProSeite teilen?

    Grüße
      David

    --
    >>Nobody will ever need more than 640k RAM!<<
    1981 Bill Gates
    1. n'abend,

      kannst du dir nicht einfach die Anzahl der Datensätze zurückgeben lassen, deren ID kleinergleich der des gesuchten ist und diese Zahl durch EinträgeProSeite teilen?

      Wie schön, dass ich den Wald vor lauter Bäumen nicht gesehen habe... :)

      weiterhin schönen abend...

      --
      Freundlich wie man war, hat man mir Großbuchstaben geschenkt.
      sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|
  2. echo $begrüßung;

    Ermittle die Seite, auf der der Datensatz mit der ID %ID% zu finden ist.
    Bisherige Lösung:

    Die ist doch schon mal nicht ganz verkehrt. Ich tät sie nur der Datenbank unterschieben. Vorausgesetzt, MySQL ORDERt zuerst und berechnet dann den @zaehler. Das solltest du mal mit ein paar unsortiert in der DB stehenden IDs probieren.

    1. Lade alle relevanten IDs (sortiert) => DBIDs

    Dafür reichen die üblichen Klauseln (WHERE, ORDER BY).

    1. Initialisiere Zähler := 0

    Dazu nehme ich eine userdefinierte Variable.
    SET @zaehler=0

    1. FOR %Y% IN DBIDs
      4-1) Erhöhe Zähler

    SELECT @zaehler:=zaehler+1 AS zaehler, ... -- zur Not noch eine Spalte (pageberechnung) AS page

    4-2) IF %Y% = %X% THEN RETURN CEILING( Zähler / DatensätzeProSeite )
    4-3) IF %Y% > %X% THEN RETURN Not-Found-till-page: CEILING( Zähler / DatensätzeProSeite )

    ... HAVING ichweißdassdudasselberhinbekommst :-)

    MySQL ist ja nicht so streng wie andere Systeme und lässt HAVING auch ohne GROUP BY gelten. Mit WHERE ausblenden geht nicht, weil zu dem Zeitpunkt der @zahler noch nicht berechnet ist.

    echo "$verabschiedung $name";

  3. Hi,

    1. Lade alle relevanten IDs (sortiert) => DBIDs
    2. Initialisiere Zähler := 0
    3. FOR %Y% IN DBIDs
      4-1) Erhöhe Zähler
      4-2) IF %Y% = %X% THEN RETURN CEILING( Zähler / DatensätzeProSeite )
      4-3) IF %Y% > %X% THEN RETURN Not-Found-till-page: CEILING( Zähler / DatensätzeProSeite )

    SELECT count(*)/DatensätzeProSeite + 1 FROM deineTabelle WHERE id <= relevanteId

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    O o ostern ...
    Fachfragen unaufgefordert per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.
    1. n'abend,

      SELECT count(*)/DatensätzeProSeite + 1 FROM deineTabelle WHERE id <= relevanteId

      Ich glaube ich lern jetzt Bäcker. Kann ja wohl nicht wahr sein, dass ich so einen komplizierten Schwachsinn fabriziere, wenn doch die Antwort auf der Hand liegt. :/

      Danke für's Entfernen des Brettes vor meinem Kopf. :)

      weiterhin schönen abend...

      --
      Freundlich wie man war, hat man mir Großbuchstaben geschenkt.
      sh:( fo:# ch:# rl:| br:> n4:& ie:{ mo:} va:) de:] zu:} fl:( ss:? ls:[ js:|