Genau den 5. Datensatz



  • Hallo Leute, ich habe folgendes Problem, wie kann ich erreichen, dass ich bspw. genau den 5. Datensatz erhalte? Oder genau den 5. bis zum 8. Datensatz. Den Primärschlüssel kann ich dazu nicht verwenden, da dieser ja nicht zwangsläufig fortlaufend nummeriert ist.

    Gruss Ishildur



  • Hmm, gar nicht? Die Reihenfolge der Daten in einer Datenbank ist normalerweise nicht bekannt, die Datenbank speichert wie sie es für das Beste hält. Wenn dein Primärschlüssel nicht fortlaufend nummeriert ist kannst du das ja zB mit einem Trigger bewerkstelligen.

    Ansonsten kannst du dir ja mal LIMIT für MySQL ansehen, bzw. rowid für Oracle.

    MfG SideWinder



  • mit was greifst du denn auf die DB zu? Wenn es VC++ ist dann kannste in deinem Set einfach moveFirst und danach move(5) machen und du stehst am 5. Datensatz!



  • mit limit gehts doch ohne probs

    SELECT *
    FROM `tolletabelle` LIMIT 4, 1

    liefert den 5ten Datensatz



  • @dreaddy: Das ist afaik nicht SQL-Standard. Außerdem ist mit diesem SQL-Statement das Ergebnis nicht definiert - je nachdem wie die Datenbank ihre Statements abspeichert, der Parser sie sortiert, etc. Für mich komplett undefiniert.

    MfG SideWinder



  • hm stimmt... komisch das phpmyadmin dann das Teil als Standardabfrage nimmt ^^.

    "Kleine Relationale-Datenbanken-Hilfe:

    Relationale Datenbanken speichern Daten als Mengen im mathematischen Sinn. Eine grundlegende Eigenschaft einer Menge ist, dass die Elemente der Menge keine definierte Reihenfolge besitzen. Deshalb wird ein SELECT ohne ORDER BY immer eine zufällige Reihenfolge liefern.

    Dass dies bei MySQL nun genau die Reihenfolge ist, in der die Elemente gespeichert wurden, haben wir wohl den Programmierern zu verdanken. Dieses Verhalten könnte sich aber bei zukünftigen MySQL-Versionen auch ändern, da es keine zugesicherte Eigenschaft ist."
    http://www.flashforum.de/forum/archive/index.php/t-78733.html

    Öö



  • @SideWinder:
    Zu LIMIT kann ich nichts sagen. Ich kenne kein MySQL. Aber was du mit der ROWID willst weiss ich nicht. Die ROWID ist die "physikalische" Adresse des Datensatzes. Er eignet sich besonders für sehr schnellen Zugriff auf z.B. vorher selektierte Datensätze. Evtl. hast du aber auch die ROWNUM gemeint. Dies ist eine "virtuelle" Spalte, die einfach die selektieren Datensätze durchnummeriert. Über ROWNUM könnte man die Aufgabe lösen. Allerdings gibt es hier schnell Probleme, da wie DREADDY schon erwähnt hat, die Daten in ungeordneter, zufälliger Reihenfolge selektiert werden. (Besonders bei der Verwendung von Parallel Query (ORACLE)) Wenn jetzt die Reihenfolge erst mit ORDER BY sortiert werden muss so kann man ROWNUM nicht mehr verwenden, da die Reihenfolge in der die einzelnen Klauseln (SELECT, FROM, WHERE, ORDER BY) bearbeitet werden hierfür ungünstig ist. WHERE wird vor ORDER BY bearbeitet. Das heißt das die z.B. ersten 5 gefundenen Datensätze selektiert werden und diese dann sortiert werden.

    @Ishildur:
    Ich glaube du hast deine Frage etwas fehlerhaft gestellt da wie schon erwähnt die Reihenfolge eines Selekt's zufällig ist und du theoretisch immer andere Datensätze bekommen könntest. Da dies nicht so ist liegt in der Programmierung und den internen Optimierern, die den Ausführungsplan für die Selekt's festlegen. Hast du physikalische Fragmentierungen durch viele DELETE und INSERT Kommandos auf einer Tabelle so kannst du evtl. ein anderes Verhalten feststellen.

    So jetzt mal ein Beispiel für einen ähnlichen Fall. Hier die Tabelle (DEPT)

    ABTNR | NAME | GEHALT
    10| King | 5000
    20| Miller | 1000
    20| Haver | 3000
    30| James | 950
    30| Martin | 1250
    30| Ward | 1400
    30| Turner | 1500
    30| Allen | 1250
    30| Blake | 2000

    Hier der Select. Ich benutze die Funktion DENSE_RANK und als zusätzliches Beispiel die Funktion RANK.

    SELECT abtnr, name, gehalt,
    DENSE_RANK() OVER( order by gehalt ) "drank",
    RANK() OVER( order by gehalt) "rank"
    FROM dept;

    und die Ausgabe ist:

    ABTNR | NAME | GEHALT | drank | rank
    30 | James | 950 | 1 | 1
    20 | Miller | 1000 | 2 | 2
    30 | Allen | 1250 | 3 | 3
    30 | Martin | 1250 | 3 | 3
    30 | Ward | 1400 | 4 | 5
    30 | Turner | 1500 | 5 | 6
    30 | Blake | 2000 | 6 | 7
    20 | Haver | 3000 | 7 | 8
    10 | King | 5000 | 8 | 9

    Natürlich kann man jetzt noch in der WHERE Klausel z.B. die Spalte "drank" einschränken WHERE drank BETWEEN 3 AND 6



  • Ich meinte rownum, aber offenbar bringt das auch nichts. Aber ich kann mir nicht vorstellen, warum ich aus einer Datenbank nur die ersten 5 Datensätze haben möchte.

    Wenns ums Darstellen in der GUI geht (immer 5 Datensätze) dann sind zuerst alle auszulesen die auf das SELECT passen und die GUI kann dann das ResultSet durchwandern und immer 5 anzeigen.

    MfG SideWinder



  • ohhhh das würde ich aber nicht machen, ich denke schon das Limit sinnvoll sein kann. jetzt vielleicht nicht bei 5 Datensätzen, aber wenn man so ne DB hat wie ich sie gerade verarbeite, dann kann das u.U. ganz schön nützlich sein. Ein netzwer, das mich gelegentlich bis auf 1 Datensatz die Sekunde ausbremst und eine Datenbank die täglich 2000 neue Datensätze bekommt! Ich glaube da muss ich nicht mehr erklären warum ihc nicht einfach mal alle Datensätze einlesen kann, und dann per GUI limitieren.
    Also alles einlesen und dann das Result limiten finde ich aus performance Gründe nicht tollerabel! 🙄



  • @Polofreak: Solange man den Cursor serverseitig beläßt, werden sowieso nur die Datensätze übertragen, die zur Zeit beim Client 'sichtbar' sind.



  • @Joe: Dafür müsste man aber eine ordentliche DB benützen, MySQL kann immer noch nicht mit serverseitigen Cursorn umgehen.

    MfG SideWinder


Anmelden zum Antworten