SQL - Kleinsten Wert ermitteln und update in spalte

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • SQL - Kleinsten Wert ermitteln und update in spalte

    Hallo,
    ich habe ein Problem und komme nicht wirklich weiter.
    Ich habe 5 Spalten
    Spalte 1-3 sind leer oder beinhalten Werte
    Spalte 4 soll den kleinsten Wert erhalten (mit update)
    Spalte 5 soll den Namen der Spalte des kleinsten Wertes erhalten.

    Ich habe folgendes versucht:

    update `db`.`table` set `d` = a WHERE a < b AND a < c;
    update `db`.`table` set `d` = b WHERE b < c AND b < a;
    update `db`.`table` set `d` = c WHERE c < a AND c < b;
    update `db`.`table` set `e` = 'a' WHERE a < b AND a < c;
    update `db`.`table` set `e` = 'b' WHERE b < c AND b < a;
    update `db`.`table` set `e` = 'c' WHERE c < a AND c < b;

    Leider funktioniert das nicht wirklich sondern liefert nur Müll.

    Ich bin über jede Hilfe dankbar - verzweifle gerade.

    Gruß

    Marco

  • #2
    <<Spalte 1-3 sind leer oder beinhalten Werte>>

    ich gehe davon aus, dass leere Werte ==NULL sind
    und NULL kann man nicht mit einem Zahl verglichen.

    wenn du ein NULL als ein 0.0 haben willst, dann muss du die werte von den ersten 3 Zeilen so ansprechen:
    IF(spaltenname is null,0,spaltenname)
    Slava
    bituniverse.com

    Kommentar


    • #3
      Zitat von piratos
      Das mit dem Update einer Spalte mit dem kleinsten Wert kann man so machen:

      Code:
      update test set `d` = least(`a`,`b`,`c`)
      Bleibt dann noch die Sache mit dem Spaltennamen
      least bringt nicht viel, da diese funktion auch bei NULL-werten scheitert.
      least(100,null,-20) liefert leider ein NULL zurück und da wir sowieso die Spaltennamen brauchen, können wir nicht viel von Code sparen.
      Also ohne if, bzw when mit der Abfrage von NULL-Werten kommt man da nicht weiter.
      Code:
      update `db`.`table` set `d` = a, `e` = 'a' 
      WHERE if(a is null,0,a) <if(b is null,0,b) AND if(a is null,0,a) < if(c is null,0,c);
      update `db`.`table` set `d` = b ,`e` = 'b' 
      WHERE if(b is null,0,b) < if(c is null,0,c) AND if(b is null,0,b) < if(a is null,0,a);
      update `db`.`table` set `d` = c,`e` = 'c' 
      WHERE if(c is null,0,c) < if(a is null,0,a) AND if(c is null,0,c) < if(b is null,0,b);
      Slava
      bituniverse.com

      Kommentar


      • #4
        @piratos warum meinst du, dass er varchar benutzt?
        die ergebnisse

        low
        NULL
        1

        sind 100% bei Integer-werten zu erwarten, also bei
        least(NULL, 2, 3)
        bekommst du ein glatte NULL

        edit: jetzt habe ich sogar mit strings versucht
        select least('1',null,'2');
        Ergebnis NULL;

        Wie hast du eine 2 in erster Zeile bekommen?
        welche DB-Version hast du?
        Zuletzt geändert von Slava; 09.08.2009, 20:29.
        Slava
        bituniverse.com

        Kommentar


        • #5
          Was aber auch korrekt ist den NULL ist nun mal der kleinste Wert.
          null kann nicht der kleinster wert sein, da ein null überhaupt kein wert ist.
          schreib ein negativer wert in eine zeile wo null ist und deine least abfrage liefert immer noch null.

          Dass die felder von defenition null waren, dass sieht man schon aus der aussage von Fragesteller als auch meinen Versuchen ihm zu helfen
          Spalte 1-3 sind leer oder beinhalten Werte
          wenn seine Tabelle keine NULL erlauben würde, dann hätte er mit seiner Abfrage keine Probleme gehabt, dann würde alles einwandfrei funktionieren.
          Zuletzt geändert von Slava; 10.08.2009, 14:54.
          Slava
          bituniverse.com

          Kommentar


          • #6
            Wenn ich einen int definiere mit Default Null bekommt man keinerlei Inhalte gespeichert, wenn ich da eine NULL explizit einfügen will.
            ich glaube, dass du eine gefährliche kombination " NOT NULL DEFAULT NULL " programmiert hast, sonnst sehe ich kein Grund, warum ein NULL nicht gespeichert sein kann.


            Ich bitte weiterhin die Aussage, dass NULL der kleinster Wert ist zurückziehen, sonnst würde die query :select NULL<1; einen 1 liefern.
            Zuletzt geändert von Slava; 10.08.2009, 14:52.
            Slava
            bituniverse.com

            Kommentar


            • #7
              OffTopic:
              @Slava: Bitte [quote]-Tags benutzen, wenn du zitierst, danke.
              I don't believe in rebirth. Actually, I never did in my whole lives.

              Kommentar


              • #8
                @wahsaga Ok.
                Slava
                bituniverse.com

                Kommentar


                • #9
                  Hi,

                  Zitat von piratos
                  Wenn ich einen int definiere mit Default Null bekommt man keinerlei Inhalte gespeichert, wenn ich da eine NULL explizit einfügen will.
                  Tabelle kann zwar definiert werden, jedoch erzeugt der Versuch eine NULL zu speichern eine Warning: #1366 Incorrect integer value:

                  Die NULL kann man tatsächlich nur rein bekommen, wenn man beim Einfügen für das Feld keinen Wert vorgibt, so das der Default zum tragen kommt.
                  Nö, das explizite Eintragen von NULL (was, wie Slava schon sagt, kein Wert ist, sondern einfach nur bedeutet, dass die Spalte leer bleibt) in eine Integerspalte ist kein Problem, solange diese Spalte leer sein darf (kein NOT NULL).

                  Zitat von piratos
                  select least(NULL,1,2)

                  verwendest, das ergibt natürlich NULLl.

                  Der Frager checkt aber Tabellenfelder und da sieht es etwas anders aus.
                  Nein, das würden die MySQL-Entwickler denke ich auch weit von sich weisen. Der Funktion least() ist das vollkommen Schnuppe, ob die Werte aus einem Tabellenfeld kommen oder direkt notiert wurden. Wenn Du NULL,1,2 durch Spaltennamen ersetzt und ein anderes Ergebnis erhältst, haben die Spalten definitiv andere Inhalte, und wenn es nur ein leerer String oder 0 anstatt "kein Wert" ist.

                  Zitat von piratos
                  Der Fragesteller hat nicht von NULL gesprochen
                  Doch:

                  Zitat von starkeeper
                  Spalte 1-3 sind leer oder beinhalten Werte
                  Genau das bedeutet NULL.
                  Außerdem wäre der TS mit seinem Abfrageergebnis sonst nicht so unzufrieden (auch hier: s. Slava), logisch gesehen sind die ersten 3 UPDATE-Statements nichts anderes als Dein Vorschlag mit least().

                  Zitat von piratos
                  Die Tabellenstruktur zum Test habe ich ja gepostet - lesen wäre gut.

                  Wenn ich da mal schlicht versuche einen leeren Datensatz einzufügen:

                  Zitat:
                  Warning: #1366 Incorrect integer value: '' for column 'a' at row 1
                  Warning: #1366 Incorrect integer value: '' for column 'c' at row 1
                  Warning: #1366 Incorrect integer value: '' for column 'd' at row 1
                  Warning: #1366 Incorrect integer value: '' for column 'e' at row 1
                  Vielleicht solltest Du Deinen Post dann selbst nochmal lesen. Die einzige Tabellenstruktur, die Du gepostet hast, war hier. Und da setzt Du doch bei den INSERTs ganz munter NULL für Spalte a...

                  Deine Fehlermeldung deutet eher darauf hin, dass Du versuchst, einen leeren String einzufügen, bzw. hier den String 'null'.

                  Der Vollständigkeit halber:
                  @starkeeper: Warum willst Du denn überhaupt Informationen doppelt speichern? Das ist i.A. Käse.

                  LG

                  Kommentar


                  • #10
                    Das hier wäre vielleicht eine Möglichkeit
                    Code:
                    UPDATE
                      test T0
                    
                      SET T0.d = IF(IF(T0.c < T0.b, T0.c, T0.b) > T0.`a`, T0.`a`,IF(T0.c < T0.b, T0.c, T0.b)), --kleinste Zahl
                            T0.e = IF(IF(T0.c < T0.b, 'c', 'b') > T0.`a`, 'a' ,IF(T0.c < T0.b, 'c', 'b'))           --Feldname mit kleinster Zahl
                    Wobei es sicherlich einfacher wäre die Daten auf mehrere Tabellen zu verteilen.

                    Gruß

                    Kommentar


                    • #11
                      @Sady82
                      teste mal damit:
                      Code:
                      select IF(null < 1, 'null kleiner eins', 'null ist nicht kleiner eins');
                      select IF(null >1, 'null groesser eins', 'null ist nicht groeser eins');
                      select null < 1 or null>1 or null=0;
                      select 2*2, 2*2+null;
                      und wenn das nicht so funktioniert, wie du es dir vorgestellt hast, dann lese noch mal was die Andere geschrieben haben.

                      mfg
                      Slava
                      bituniverse.com

                      Kommentar


                      • #12
                        Dafür gibts auch eine Lösung:

                        Code:
                        UPDATE
                          test T0
                        
                          SET T0.d = IF(
                                          IF( IFNULL(T0.c,0) < IFNULL(T0.b,0),
                                            IFNULL(T0.c,0), IFNULL(T0.b,0)
                                          ) 
                                              > IFNULL(T0.`a`,0),
                                              IFNULL(T0.`a`,0), IF(
                                                                    IFNULL(T0.c,0) < IFNULL(T0.b,0),
                                                                    IFNULL(T0.c,0), IFNULL(T0.b,0)
                                                                  )
                                       ),
                              T0.e = IF(IF(IFNULL(T0.c,0) < IFNULL(T0.b,0), 'c', 'b') > IFNULL(T0.`a`,0), 'a' ,IF(IFNULL(T0.c,0) < IFNULL(T0.b,0), 'c', 'b'))
                        Das wäre allerdings auch nur ein Workaround. Wenn man weiß, dass man mit Werten in der Datenbank mathematische Operationen durchführen will, muss man das Design auch entsprechend festlegen.

                        Z.B:
                        Code:
                        CREATE TABLE `test` (
                          `a` int(11) NOT NULL default '0',
                          `b` int(11) NOT NULL default '0',
                          `c` int(11) NOT NULL default '0',
                          `d` int(11) NOT NULL default '0',
                          `e` varchar(10) NOT NULL
                        ) ENGINE=MyISAM DEFAULT CHARSET=latin1;
                        Gruß

                        Kommentar


                        • #13
                          obere teil würde funktionieren, die untere nicht
                          Code:
                          T0.e = IF([B]IF(IFNULL(T0.c,0) < IFNULL(T0.b,0), 'c', 'b') > IFNULL(T0.`a`,0)[/B], 'a' ,IF(IFNULL(T0.c,0) < IFNULL(T0.b,0), 'c', 'b'))
                          weil du buchstabe mit dem zahl vergleichst.
                          solche fehler kommen immer wieder, wenn code unübersichtlich ist
                          Slava
                          bituniverse.com

                          Kommentar


                          • #14
                            Richtig! Deshalb deshalb ist die beste Lösung immer die einfachste: Die Feldtypen in der DB richtig deklarieren

                            Kommentar

                            Lädt...
                            X