Pieter: SQL: Abfrage zum nächsttieferen Wert

Liebes Forum,

ich weiß nichtmals, wonach ich googlen soll.

Es sei eine Tabelle :

ID | Value
0    10
1    20
2    30
3    40

Nun brauche ich eine Abfrage, die mir zu einem beliebigen Wert, der nicht in der Tabelle vorkommt, den "nächsttieferen" Datensatz zurückliefert. ZB schmeiß ich den Value 23 rein und bekomme den Datensatz mit der ID 1, Value 20 zurück.

Wie mach ich´s?

Lieben Gruß,
Pieter

  1. Hallo Pieter,

    Es sei eine Tabelle :

    ID | Value
    0    10
    1    20
    2    30
    3    40

    Nun brauche ich eine Abfrage, die mir zu einem beliebigen Wert, der nicht in der Tabelle vorkommt, den "nächsttieferen" Datensatz zurückliefert. ZB schmeiß ich den Value 23 rein und bekomme den Datensatz mit der ID 1, Value 20 zurück.

    Das Ergebnis ist in diesem Fall eindeutig.

    Was hättest Du gerne in folgendem Fall?

    ID | Value
    0    10
    1    20
    2    20
    3    30

    Grundsätzlich gibt es die verschiedensten Möglichkeiten. Zum Beispiel bietet es sich an, zunächst eine geeignete WHERE-Klausel zu verwenden, die Datensätze geeignet zu sortieren und die Ergebnismenge wie gewünscht zu limitieren.

    Bitte beachte, dass die SQL-Syntax zum Limitieren der Ergebnismenge vom SQL-Dialekt des DBMS abhängt.

    Eine andere Möglichkeit wäre es mit einem Subselect und der Aggregatsfunktion MAX() zu arbeiten.

    Was Du verwenden kannst, wie die Abfrage exakt aussehen kann, das hängt von Deinem Datenbankmanagementsystem (DBMS) ab - und von dem Sprachumfang, den das DBMS unterstützt. Beim weit verbreiteten DBMS MySQL ist es extrem versionsabhängig, was Du (nicht) verwenden kannst.

    Wenn Dir meine Angaben noch nicht genügend weiterhelfen, so gib uns bitte Dein DBMS inklusive Version an.

    Freundliche Grüße

    Vinzenz

    1. Hallo Vinzenz,

      vielen Dank erstmal!

      Das Ergebnis ist in diesem Fall eindeutig.

      Was hättest Du gerne in folgendem Fall?

      ID | Value
      0    10
      1    20
      2    20
      3    30

      Das kann ich (gottseidank) ausschließen. :) Kann nicht vorkommen.

      Grundsätzlich gibt es die verschiedensten Möglichkeiten. Zum Beispiel bietet es sich an, zunächst eine geeignete WHERE-Klausel zu verwenden, die Datensätze geeignet zu sortieren und die Ergebnismenge wie gewünscht zu limitieren.

      Wäre das sowas wie:

      SELECT * FROM myTable WHERE Value < 23 ORDER BY Value LIMIT 1;

      Aber das ist doch nicht eindeutig, oder? SQL könnte dann doch auch den Datensatz 0 mit Value 10 zurückliefern?

      Eine andere Möglichkeit wäre es mit einem Subselect und der Aggregatsfunktion MAX() zu arbeiten.
      Wenn Dir meine Angaben noch nicht genügend weiterhelfen, so gib uns bitte Dein DBMS inklusive Version an.

      Oracle10g wäre das. Wie in etwas sähe denn die Verwendung von MAX() aus? Ich habe da leider keine genaue Vorstellung...

      Danke,
      Pieter

      1. Hi,

        Oracle10g wäre das. Wie in etwas sähe denn die Verwendung von MAX() aus? Ich habe da leider keine genaue Vorstellung...

        *args*, na ja, was suchst du denn? Du suchst den maximalen Wert, der kleiner ist als ein vorgegebener, dank Subselect kannst du dann auch die entsprechende ID filtern:
        SELECT id
        FROM mytable
        WHERE value = (SELECT MAX(value) FROM mytable WHERE value <= xyz)

        MfG
        Rouven

        --
        -------------------
        ss:) zu:) ls:& fo:) de:< va:{ ch:? sh:) n4:( rl:? br:$ js:| ie:) fl:(
        1. Hi,

          nicht jedes DBMS kann mit Derived Tables / Sub-Queries ....

          Ciao, Frank

          1. yo,

            nicht jedes DBMS kann mit Derived Tables / Sub-Queries ....

            hier geht es aber nicht um jedes, sondern ganz konkret um oracle 10g. und oracle kann schon lange mit subquries umgehen...

            Ilja

        2. Hey, fein! Damit komm ich weiter!

          Danke, auch an alle anderen! Ich werde mal beide Methoden testen!

          Pieter

      2. Hallo,

        SELECT * FROM myTable WHERE Value < 23 ORDER BY Value LIMIT 1;

        Aber das ist doch nicht eindeutig, oder? SQL könnte dann doch auch den Datensatz 0 mit Value 10 zurückliefern?

        Doch, denn:

        • Mit der Where-Klausel hast du das Ergebnis auf Zeilen mit Value < 23 begrenzt
        • Das weitere Ergebnis mit der Order-By-Klausel nach einem sinkenden Value-Wert (drum musst du ORDER BY Value DESC) schreiben sortiert ....
        • Und mit LIMIT 1 auf einen Eintrag limitiert.

        So bekommst du EINEN Eintrag von denen, die KLEINER als 23 sind und von denen den GRÖßTEN.
        Das wäre doch alles, oder?

        werbeklaus

      3. hi,

        SELECT * FROM myTable WHERE Value < 23 ORDER BY Value LIMIT 1;

        Aber das ist doch nicht eindeutig, oder? SQL könnte dann doch auch den Datensatz 0 mit Value 10 zurückliefern?

        Nein, könnte es nicht - weil zuerst alle der Bedingung entsprechenden Datensätze sortiert werden, und dann aus dieser sortierten Menge der erste genommen wird.

        gruß,
        wahsaga

        --
        /voodoo.css:
        #GeorgeWBush { position:absolute; bottom:-6ft; }