Schnaps: DB Abfrage Array durchlaufen und sortieren

Guten Morgen Forum,

ich habe hier eine Datenbank Abfrage, die mich mit einem netten Array versorgt.

$sql="SELECT adresse,besitzer,alli_id,extra_id FROM planet WHERE alli_id='1'"

Nach dem fetch_array hab ich dann ja, wie immer mein Array (assoc), mit den ganzen Werten.
Bsp.: $row['adresse'],$row['besitzer']

Und um das Feld adresse geht es auch.

In dem Feld adresse sind immer Werte (varchar,leider !) in dem Format xx:xxx:xx
 gespeichert (x ist jeweils eine Ziffer, ohne vorgestellte Nullen). Bsp.: 6:57:10

Ich möchte das ganze Array nun nach diesem Feld sortieren. und zwar so, dass zuerst nach dem Wert hinter dem ersten Doppelpunkt sortiert wird und  dann nach dem letzten Wert.

Ich hatte überlegt, die Werte mit explode(":",$row['adresse']) evtl zu trennen, dass ich die drei Ziffernblöcke einzelnd habe. Diese würde ich dann in das Array $row packen um dann danach zu sortieren.
Aber da hab ich gerade ein Brett vorm Kopp, weiß nicht genau wie ich das umsetzen kann.

Sollte ich dann wenn ich das Array in der while Schleife abarbeite die Werte exploden und die dann jeweils in $row dazu packen? Dafür müßte ich ja 3 neue Keys in das Array packen, wie mach ich das denn?

Wie könnte ich danach das Array zuerst nach der einen und sekundär nach der anderen Spalte sortieren?

Ich bin auch offen für einen anderen Ansatz, evtl kann man das ja auch direkt mit einer Datenbank Abfrage machen?

Oder ihr habt einen komplett anderen Vorschlag.

Und bitte nicht gleich meckern, mir ist nun da ich vor diesem Problem stehe auch aufgefallen, dass meine Datenbank Strucktur in dem Punkt dumm ist. Es wäre besser gewesen das Feld Adresse in drei einzelnde Interger Werte zu packen, aber dafür ist es nun leider zu spät.
Die Änderungen würden erheblich zu lange dauern. Beim nächsten mal werde ich versuchen die DB genauer zu überdenken.Ist halt schwer immer so weit vorraus zu planen.

(  Ist nicht meine Stärke ;-)  )

Würde mich über Hilfe freuen

Gruß
Schnaps

  1. Moin!

    Du solltest mit der MySQL-String-Funktion

    SUBSTRING_INDEX(str,delim,count)

    experimentieren.

    Returns the substring from string str before count occurrences of the delimiter delim. If count is positive, everything to the left of the final delimiter (counting from the left) is returned. If count is negative, everything to the right of the final delimiter (counting from the right) is returned.

    Gibt einen Teilstring (str) vor dem gezähltem (count) Auftreten des Trenner (delim) zurück. Ist (count) positiv wird alles vom letzten (von links gezähltem) Trenner zurückgegeben. Ist count negativ wird alle, was rechts von

    mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', 2);
            -> 'www.mysql'
    mysql> SELECT SUBSTRING_INDEX('www.mysql.com', '.', -2);
            -> 'mysql.com'

    Also:

    SELECT SUBSTRING_INDEX(adresse, ':', 1) AS addr_part1 FROM table ....
    -> Liefert deinen ersten Abschnitt
    SELECT SUBSTRING_INDEX(adresse, ':', -1) AS addr_part3 FROM table ....
    -> Liefert deinen dritten Abschnitt

    für den in der Mitte müssen wir verschachteln: Wir hole uns die ersten beiden (innen) und aus dem den rechten (aussen):

    SELECT SUBSTRING_INDEX(SUBSTRING_INDEX(adresse, ':', 2), ':', -1) AS addr_part2 FROM table ....
    -> Liefert deinen mittleren Abschnitt

    Ungetestet: es kann sein, da ist Feinschliff nötig.

    MFFG (Mit freundlich- friedfertigem Grinsen)

    fastix®

    --
    Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Development. Auch  für seriöse Agenturen.
    1. Hallo

      Vielen Dank für deine super Antwort, hat mir sehr geholfen!!!

      Hab die drei Aufrufe nun mal zusammen gepackt, und es geht!!!!

      Hier der Aufruf:

      SELECT SUBSTRING_INDEX( planeten_adresse, ':', 1 ) AS gal, SUBSTRING_INDEX( SUBSTRING_INDEX( planeten_adresse, ':', 2 ) , ':', -1 ) AS sol, SUBSTRING_INDEX( planeten_adresse, ':', -1 ) AS pla
      FROM planet where alli_id=1
      ORDER BY sol,pla ASC

      Ein kleines Problem habe ich aber noch, der sortiert die Werte nun als Strings, also 111 kommt vor 20..., ich habe dann mal nach umwandel Funktionen von mySQl geschaut und da gab es cast() oder convert(), aber die wandeln nur in Binary um, hab da nichts gesehen, wie ich es in einen normalen Int Wert wandeln kann, das die Sortierung auch funzt.

      Gruß
      schnaps

      1. Hallo Schnapps,

        vielleicht ist es nicht verkehrt, wenn du aus deiner Spalte Planeten_adresse DREI Spalten pl_ADR1, pl_ADR2 und pl_ADR3 vom Typ NUMBER(10) machst. Diese kannst du besser sortieren.

        Du kannst ja mit einem regulären Ausdruck nachprüfen ob der String wirklich das Format n*:n*:n* aufweist (n ist Ziffer von 1-9, * ist beliebig). Mit explode() kannst du dann den String zerlegen und die Werte in die entsprechenden Zeilen schreiben.

        Dann kannst du das select-statement laufen lassen und werte bei "ORDER BY" kannst du ja wieder konkatenieren.

        So wäre, skizziert, meine Vorgehensweise.

        Grüße,

        Wolfram

      2. Moin!

        Ein kleines Problem habe ich aber noch, der sortiert die Werte nun als Strings, also 111 kommt vor 20..., ich habe dann mal nach umwandel Funktionen von mySQl geschaut und da gab es cast() oder convert(), aber die wandeln nur in Binary um, hab da nichts gesehen, wie ich es in einen normalen Int Wert wandeln kann, das die Sortierung auch funzt.

        Gruß
        schnaps

        Wieso? steht doch dort...

        To cast a string to a numeric value in numeric context, you don't normally have to do anything. Just use the string value as though it were a number:

        SELECT SUBSTRING_INDEX( planeten_adresse, ':', 1 )*1 AS gal, SUBSTRING_INDEX( SUBSTRING_INDEX( planeten_adresse, ':', 2 ) , ':', -1 )*1 AS sol, SUBSTRING_INDEX( planeten_adresse, ':', -1 )*1 AS pla
        FROM planet where alli_id=1
        ORDER BY sol,pla

        http://dev.mysql.com/doc/mysql/en/cast-functions.html

        MFFG (Mit freundlich- friedfertigem Grinsen)

        fastix®

        --
        Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Development. Auch  für seriöse Agenturen.
        1. Moin!

          Darüber hinaus kannst Du auch 3 neue Spalten als INT anlegen und diese in einem Rutsch mit UPDATE füllen. Danach hast Du es einfacher. Vor allem kannst Du die Tabelle nach den Spalten auch indexieren und sogar vorsortieren, was bei größeren Datentabellen dann durchaus eine Performance-Gewinn ergibt.

          UPDATE planet
          SET
            gal = SUBSTRING_INDEX( planeten_adresse, ':', 1 ),
            sol = SUBSTRING_INDEX( SUBSTRING_INDEX( planeten_adresse, ':', 2 ), ':', -1 )
            pla = SUBSTRING_INDEX( planeten_adresse, ':', -1 )
          WHERE 1

          MFFG (Mit freundlich- friedfertigem Grinsen)

          fastix®

          --
          Als Freiberufler bin ich immer auf der Suche nach Aufträgen: Schulungen, Development. Auch  für seriöse Agenturen.
        2. echo $begrüßung;

          To cast a string to a numeric value in numeric context, you don't normally have to do anything. Just use the string value as though it were a number:

          ORDER BY sol,pla

          Das weiß das MySQL aber nicht, dass du hier einen numerischen Kontext haben möchtest. sol und pla sind vom Typ "string". Um den numerischen Kontext zu erhalten kann man ORDER BY 0 + sol, 0 + pla schreiben.

          echo "$verabschiedung $name";

          1. Moin!

            SELECT
               SUBSTRING_INDEX( planeten_adresse, ':', 1 )*1 AS gal,
               SUBSTRING_INDEX( SUBSTRING_INDEX( planeten_adresse, ':', 2 ) , ':', -1 )*1 AS sol,
               SUBSTRING_INDEX( planeten_adresse, ':', -1 )*1 AS pla
            FROM planet where alli_id=1
            ORDER BY sol,pla;

            Das weiß das MySQL aber nicht, dass du hier einen numerischen Kontext haben möchtest. sol und pla sind vom Typ "string". Um den numerischen Kontext zu erhalten kann man ORDER BY 0 + sol, 0 + pla schreiben.

            Du hast übersehen, dass ich die erhaltenen Werte mit 1 multiplziziert habe?

            MFFG (Mit freundlich- friedfertigem Grinsen)

            fastix®

            --
            Als Freiberufler bin ich immer auf der Suche nach Aufträgen: S» » chulungen, Development. Auch  für seriöse Agenturen.
            1. echo $begrüßung;

              Du hast übersehen, dass ich die erhaltenen Werte mit 1 multiplziziert habe?

              Ja, hab ich. Und nicht nur deshalb wünsche ich mir (und für den Lerneffekt beim Fragenden) für das nächste Mal, dass du beschreibst, mit welchen Mitteln man zur Lösung kommt, anstatt sie unkommentiert im Quelltext zu verstecken.[*]

              echo "$verabschiedung $name";

              [*] Ich habe den Eindruck, dass der Satz irgendwie unfreundlich klingt, was aber nicht meine Absicht ist.

              1. Moin!

                To cast a string to a numeric value in numeric context, you don't normally have to do anything. Just use the string value as though it were a number:

                Du hast übersehen, dass ich die erhaltenen Werte mit 1 multiplziziert habe?
                Ja, hab ich. Und nicht nur deshalb wünsche ich mir (und für den Lerneffekt beim Fragenden) für das nächste Mal, dass du beschreibst, mit welchen Mitteln man zur Lösung kommt, anstatt sie unkommentiert im Quelltext zu verstecken.[*]

                Ich habe die Information nicht versteckt. Die von mir oben eingefügte (und jetzt unten auch übersetzte) Beschreibung aus dem kritisierten Beitrag sagt doch ganz eindeutig:

                "Um einen String als einen numerischen Wert in einem numerischen Zusammenhang zu verwenden müssen Sie normalerweise nichts machen. Benutzen Sie den String einfach so als wäre er eine Zahl."

                Das genau ist die Beschreibung der Lösung. Die im Quelltext dargestellte Multiplikation mit 1 ist nur eine Form der Realisierung und ich habe bewusst den Quelltext nicht einfach verändert, sondern auch durch Entfernung der dies anzeigenden Zeichen erkenntlich gemacht, dass es sich eben nicht um den original belassenen Quelltext des Fragenden handelt.

                <Scherz>Außerdem habe ich einen schöde-trivial-überlebenswichtigen-monetären Grund hier nicht alles in vollkommener Tiefe zu erklären. Zu dem Zweck halte ich gegen Geld wunderschöne Seminare.</Scherz>

                MFFG (Mit freundlich- friedfertigem Grinsen)

                fastix®

                --
                Tage sind nicht unterschiedlich lang sondern unterschiedlich breit.
  2. Hi,

    $sql="SELECT adresse,besitzer,alli_id,extra_id FROM planet WHERE alli_id='1'"

    Nach dem fetch_array hab ich dann ja, wie immer mein Array (assoc), mit den ganzen Werten.
    Bsp.: $row['adresse'],$row['besitzer']

    In dem Feld adresse sind immer Werte (varchar,leider !) in dem Format xx:xxx:xx
    gespeichert (x ist jeweils eine Ziffer, ohne vorgestellte Nullen). Bsp.: 6:57:10

    Ich möchte das ganze Array nun nach diesem Feld sortieren.

    Das würde ich schon vom DB-Server erledigen lassen (dafür gibt es ja ORDER BY).

    Ist halt (je nachdem, ob die Anzahl Ziffern immer gleich ist oder nicht) etwas Fummelei mit Stringfunktionen, um die Sortierausdrücke hinzubekommen.

    U.U. ist aber auch (wenn die :-getrennten Daten immer wieder getrennt benutzt werden) eine andere DB-Struktur sinnvoller (einzelne Spalten für die Teile - wenn dann doch mal der gesamte String gebraucht wird, gibt es in MySQL z.B. die CONCAT-Funktion)

    cu,
    Andreas

    --
    Warum nennt sich Andreas hier MudGuard?
    Schreinerei Waechter
    Fachfragen per E-Mail halte ich für unverschämt und werde entsprechende E-Mails nicht beantworten. Für Fachfragen ist das Forum da.