select... aber wie??

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

  • select... aber wie??

    Hallo erstmal.

    Ich suche nach dem letzten Status 0 Wert einer UID und
    dem dazugehörigen (selbe UID) Status 1 Wert vor dem letzten Status 0 Wert.



    Das ist meine Tabelle:

    mysql> select * from dznw;
    +----+------+-----------------------+--------+
    | id | uid | datum | status |
    +----+------+-----------------------+--------+
    | 1 | 1000 | 2009-01-24 08:01:01 | 1 | (1..... arbeitsbeginn)
    | 2 | 1000 | 2009-01-24 10:12:15 | 0 | (0..... arbeitsende)
    | 3 | 1000 | 2009-01-24 10:17:23 | 1 |
    | 4 | 1000 | 2009-01-24 12:06:46 | 0 |
    | 5 | 2222 | 2009-01-24 12:30:14 | 1 |
    | 6 | 2222 | 2009-01-24 14:03:06 | 0 |
    | 7 | 2222 | 2009-01-24 14:27:27 | 1 |
    | 8 | 1000 | 2009-01-24 15:04:23 | 1 |
    | 9 | 2222 | 2009-01-25 08:46:18 | 0 |
    | 10 | 1000 | 2009-01-25 08:47:39 | 0 |
    | 11 | 1000 | 2009-01-25 12:00:00 | 1 |
    +----+------+---------------------+--------+
    11 rows in set (0.00 sec)

    Jetzt benutze ich folgende Abfrage:


    mysql> SELECT `id`, UNIX_TIMESTAMP(`datum`) AS `timestamp` FROM `dznw` WHERE `status` = '0' ORDER BY `id` DESC LIMIT 1;
    +----+------------+
    | id | timestamp |
    +----+------------+
    | 10 | 1232869659 |
    +----+------------+
    1 row in set (0.01 sec)

    Somit bekomme ich genau den Wert den ich suche.



    Jetzt zu meinem PROBLEM:
    Aber wenn ich jetzt nach dem letzten Status 1 Wert „vor“ dem letzten Status 0 Wert suche weiß ich nicht wie das funktionieren soll.
    Diese Abfrage funktioniert nur wenn der letzte Status Wert eine 0 enthält,


    mysql> SELECT `id`, UNIX_TIMESTAMP(`datum`) AS `timestamp` FROM `dznw` WHERE `status` = '1' AND `id` < 35 ORDER BY `id` DESC LIMIT 1;
    +----+------------+
    | id | timestamp |
    +----+------------+
    | 11 | 1232881200 |
    +----+------------+
    1 row in set (0.00 sec)

    Was mach ich falsch

  • #2
    id < 35
    sollte wohl eher
    id < 10
    lauten in deinem Beispiel... eventuell ist das schon der Fehler.

    Ein netter Guide zum übersichtlichen Schreiben von PHP/MySQL-Code!

    bei Klammersetzung bevorzuge ich jedoch die JavaCoding-Standards
    Wie man Fragen richtig stellt

    Kommentar


    • #3
      Re: select... aber wie??

      Original geschrieben von tina23
      Ich suche nach dem letzten Status 0 Wert einer UID und
      dem dazugehörigen (selbe UID) Status 1 Wert vor dem letzten Status 0 Wert.
      Mit WHERE uid = x reduzierst du das Ergebnis schon mal auf alle Datensätze mit dieser UID.
      Mit ORDER BY datum DESC sortierst du das reduzierte Ergebnis nach dem Zeitstempel, den neuesten Datensatz zuerst.

      Wenden wir das mal auf deine oben geposteten Daten an, erhalten wir folgendes für UID 1000:

      ... WHERE uid = 1000 ORDER BY datum DESC;
      +----+------+-----------------------+--------+
      | id | uid | datum | status |
      +----+------+-----------------------+--------+
      | 11 | 1000 | 2009-01-25 12:00:00 | 1 |
      | 10 | 1000 | 2009-01-25 08:47:39 | 0 |
      | 8 | 1000 | 2009-01-24 15:04:23 | 1 |
      | 4 | 1000 | 2009-01-24 12:06:46 | 0 |
      | 3 | 1000 | 2009-01-24 10:17:23 | 1 |
      | 2 | 1000 | 2009-01-24 10:12:15 | 0 |
      | 1 | 1000 | 2009-01-24 08:01:01 | 1 |

      Wir wollen jetzt davon den ersten Datensatz mit Status 0, dessen Vorgänger Status 1 hat und dessen Vorvorgänger Status 0 hat. Das wäre der mit id 4.

      Jetzt könnten wir die Query von eben als Subselect verwenden. Aber es geht auch einfacher: Wir nutzen die Semantik der Daten. Es geht hier ja um Arbeitszeiten eines "Users". Status 1 ist Arbeitsbeginn, Status 0 ist -ende. Wir wissen, dass auf jeden Anfang ein Ende und dann wieder ein Anfang folgen muss (wir haben ja chronologisch sortiert).
      Das heißt, wenn wir jeden Datensatz mit Status 1 streichen, haben wir folgendes:

      ... WHERE uid = 1000 AND status = 0 ORDER BY datum DESC;
      +----+------+-----------------------+--------+
      | id | uid | datum | status |
      +----+------+-----------------------+--------+
      | 10 | 1000 | 2009-01-25 08:47:39 | 0 |
      | 4 | 1000 | 2009-01-24 12:06:46 | 0 |
      | 2 | 1000 | 2009-01-24 10:12:15 | 0 |

      Streichen wir die Bedingung mit Status 1 auch aus unserer Anforderung:
      Wir wollen jetzt davon den ersten Datensatz mit Status 0, dessen Vorgänger Status 0 hat. Das wäre immernoch der mit id 4. Gottseidank.

      Die so vereinfachte Anforderung können wir spielend leicht erfüllen. Es genügt LIMIT 1,1.

      Also wäre eine Lösung: ... WHERE uid = 1000 AND status = 0 ORDER BY datum DESC LIMIT 1,1

      Kommentar

      Lädt...
      X