<= (kleiner gleich) in WHERE funktioniert nicht (richtig)?

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

  • <= (kleiner gleich) in WHERE funktioniert nicht (richtig)?

    Hallo,

    ich habe da ein winziges Problem mit einem Teil einer MySQL-Abfrage, welcher nicht so funktioniert, wie ich es erwarte.

    Tabelle:
    Code:
    mysql> DESCRIBE product_price;
    +------------+------------------+------+-----+---------+----------------+
    | Field      | Type             | Null | Key | Default | Extra          |
    +------------+------------------+------+-----+---------+----------------+
    | id         | int(10) unsigned | NO   | PRI | NULL    | auto_increment |
    | product_id | int(10) unsigned | NO   |     | NULL    |                |
    | start_date | date             | NO   |     | NULL    |                |
    | price      | decimal(5,2)     | NO   |     | NULL    |                |
    +------------+------------------+------+-----+---------+----------------+
    
    mysql> SELECT * FROM product_price;
    +----+------------+------------+--------+
    | id | product_id | start_date | price  |
    +----+------------+------------+--------+
    |  1 |          1 | 2015-01-01 |  12.50 |
    |  2 |          2 | 2015-01-01 |   9.80 |
    |  3 |          3 | 2015-01-01 | 135.95 |
    |  4 |          1 | 2015-03-01 |  17.80 |
    |  5 |          3 | 2015-05-01 | 150.00 |
    |  6 |          4 | 2015-05-01 |  75.39 |
    +----+------------+------------+--------+
    Abfrage 1:
    Code:
    mysql> SELECT * FROM `product_price` WHERE `product_id`=1 AND `start_date`<='2015-[B][U]02[/U][/B]-01' LIMIT 1;
    +----+------------+------------+-------+
    | id | product_id | start_date | price |
    +----+------------+------------+-------+
    |  1 |          1 | 2015-01-01 | 12.50 |
    +----+------------+------------+-------+
    1 row in set (0.00 sec)
    Ergebnis 12.50 ist richtig.

    Abfrage 2:
    Code:
    mysql> SELECT * FROM `product_price` WHERE `product_id`=1 AND `start_date`<='2015-[B][U]03[/U][/B]-01' LIMIT 1;
    +----+------------+------------+-------+
    | id | product_id | start_date | price |
    +----+------------+------------+-------+
    |  1 |          1 | 2015-01-01 | 12.50 |
    +----+------------+------------+-------+
    1 row in set (0.00 sec)
    Ergebnis 12.50 ist falsch, sollte 17.80 sein. Und `start_date` sollte 2015-03-01 sein.

    Habe ich da einen Denkfehler? Oder gibt es eine Besonderheit bei MySQL die ich nicht kenne?

    Bin dankbar für Hinweise...

    Gruß
    andyB.

  • #2
    2015-01-01 ist kleiner als 2015-03-01. Und demzufolge ist das Ergebnis deiner Abfrage vollkommen korrekt.
    I don't believe in rebirth. Actually, I never did in my whole lives.

    Kommentar


    • #3
      Wenn ich jetzt das Datum in der WEHRE-Klausel auf 2015-03-05 setzte gibt er mir aber auch den Datensatz mit dem Datum 2015-01-01 zurück.

      Liegt das am LIMIT 1?

      Wenn ich das weg lasse, bekomme ich beide Datensätze zurück.

      Gibt es eine Methode, wie ich die Anzahl der Datensätze einschränke?
      Im Beispiel sind ja 'nur' zwei Datensätze vorhanden. In Wirklichkeit aber viel mehr.

      Kommentar


      • #4
        Du selektierst erst mal alle Datensätze mit Datum kleiner-gleich, und lässt dir von der Datenbank dann den „ersten“ davon zurückgeben – und welcher dieser „erste“ ist, ist mehr oder weniger Zufall, weil du der Datenbank keine Anweisung gegeben hast, die Datensätze zunächst nach irgendeinem Kriterium zu sortieren, bevor der erste davon genommen wird.

        Also: Zusätzlich die gewünschte Sortiung angeben.
        I don't believe in rebirth. Actually, I never did in my whole lives.

        Kommentar


        • #5
          Du meinst also, dass:
          Code:
          mysql> SELECT * FROM `product_price` WHERE `product_id`=1 AND `start_date`<='2015-03-01' [B][U]ORDER BY `start_date` DESC[/U][/B] LIMIT 1;
          das Problem löst?

          Ich probiere das später mal aus.
          Zuletzt geändert von goth; 20.11.2015, 19:04.

          Kommentar


          • #6
            Das ist tatsächlich die Lösung.
            Irgendwie stand ich auf'm Schlauch...

            wahsaga!

            Kommentar


            • #7
              Die Lösung mit ORDER BY mit LIMIT ist aber ganz schön "teuer".

              Nehmen wir mal an die Tabelle hat 5 Mio. Datensätze, wovon 1 Mio <= 2015-03-01 sind. Bei deiner Abfrage muss die DB aber erst 1 Mio Datensätze ermitteln und sortieren um später nur einen Datensatz der Middleware PHP zu übergeben.

              Mag sein das 1 Mio übertrieben ist, aber wächst die Datenbank, viele Tabellen und Joins, kann bei einem "kartesischen Produkt" schon bei wenigen 1000 Datensätzen dieser Flaschenhals auftreten. Zu Beginn beim Programmieren mit wenigen Daten wird man nichts merken, aber wenn es Live geht, fangen die Performance Probleme an.

              Lieber weiter mit WHERE arbeiten (bspw. Timeframe) statt nur auf ORDER BY und LIMIT zu setzen. Auch wenn es tut, ich finde die WHERE Condition alleine mit <= 2015-03-01 ist ganz schön dürftig.

              Kommentar

              Lädt...
              X