Raimund: MySQL Abfrage

Hi,

kann mir jemand helfen wie ich folgende Abfragen machen könnte.
In meiner Tabelle habe ich eine Spalte mit DATE (zB 2012-01-16)

  • Ich möchte eine Abfrage die mir alle Einträge ausgibt die diesen Monats sind, also alle zB vom 2012-01-xx.

  • Eine Abfrage die mir alle Einträge von den nächsten 14 Tagen ausgibt zB vom 2012-01-16 bis 2012-01-29

Vielen Dank für eure Hilfe.
mfg Raimund

    • Ich möchte eine Abfrage die mir alle Einträge ausgibt die diesen Monats sind, also alle zB vom 2012-01-xx.

    • Eine Abfrage die mir alle Einträge von den nächsten 14 Tagen ausgibt zB vom 2012-01-16 bis 2012-01-29

    Die Datums und Zeitfunktionen sind sehr einfach und leicht verständlich - du musst also nur deine beiden Anforderungen ausformulieren.

    DATEDIFF(), NOW(), MONTH() und YEAR() wirst du vermutlich benötigen.

    1. Hello,

      • Ich möchte eine Abfrage die mir alle Einträge ausgibt die diesen Monats sind, also alle zB vom 2012-01-xx.

      • Eine Abfrage die mir alle Einträge von den nächsten 14 Tagen ausgibt zB vom 2012-01-16 bis 2012-01-29

      Die Datums und Zeitfunktionen sind sehr einfach und leicht verständlich - du musst also nur deine beiden Anforderungen ausformulieren.

      DATEDIFF(), NOW(), MONTH() und YEAR() wirst du vermutlich benötigen.

      Ich würde für den Zeitraum eher für adddate() und Interval plädieren
      http://dev.mysql.com/doc/refman/5.5/en/date-and-time-functions.html#function_adddate

      Liebe Grüße aus dem schönen Oberharz

      Tom vom Berg

      --
       ☻_
      /▌
      / \ Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
  1. Habe es jetzt so gelöst:

    SELECT * FROM calendar WHERE DATE_FORMAT(date,'%Y-%m') = '2012-01'

    und

    SELECT * FROM calendarWHEREdate BETWEEN '2012-01-15' AND '2012-01-30'

    gibt es einen bessere Lösung?

    mfg

    1. Hi,

      SELECT * FROM calendar WHERE DATE_FORMAT(date,'%Y-%m') = '2012-01'

      hier kann MySQL i.d.R. keinen Index nutzen, weil MySQL berechnete Indize nicht kennt. Die Abfrage wird dann u.U. langsam. Wenn du ein Datum abfragen willst, dann frage einfach mit "BETWEEN ... AND" ab (so wie du es in deinem zweiten Beispiel machst), als Begrenzer kannst du den ersten des gesuchten Monats und den ersten des folgenden Monats nehmen.

      Bis die Tage,
      Matti

    2. SELECT * FROM calendar WHERE DATE_FORMAT(date,'%Y-%m') = '2012-01'

      Ja, das ist eine Lösung - aber ein Datum in einen String zu konvertieren und diesem dann für einen Vergleich heranziehen ist etwas hölzern.

      SELECT * FROM calendarWHEREdate BETWEEN '2012-01-15' AND '2012-01-30'

      Das mag in diesem Fall funktionieren, aber du willst dir doch nicht ernsthaft die nächsten 14 Tage manuell ausrechnen - inklusive Schalttagen?

      gibt es einen bessere Lösung?

      Ja.

  2. Vielen Dank für eure Hilfe

    nun schaut mein Ergebnis so aus:

      
    SELECT *  
    FROM   `calendar`  
    WHERE  `date` BETWEEN '2012-01-01' AND DATE_SUB(DATE_ADD('2012-01-01', INTERVAL 1 MONTH), INTERVAL 1 DAY)  
    
    

    und

      
    SELECT *  
    FROM   `calendar`  
    WHERE  `date` BETWEEN '2012-01-16' AND DATE_ADD('2012-01-16', INTERVAL 13 DAY)  
    
    

    ich hoffe das ist nun der Beste Lösungsweg :)

    mfg

    1. Hi,

      SELECT *
      FROM   calendar
      WHERE  date BETWEEN '2012-01-01' AND DATE_SUB(DATE_ADD('2012-01-01', INTERVAL 1 MONTH), INTERVAL 1 DAY)

        
      welchen Typ hat denn die Spalte date? Wenn es ein DateTime ist, könntest du u.U. die Einträge des letzten Tages des Monats verpassen. Wenn es ein Date ist, dann sollte es (so vom reinen Hinsehen) OK sein.  
        
      Bis die Tage,  
      Matti
      
      -- 
      [Webapplikationen in C++ entwickeln](http://tntnet.org/)
      
    2. Hallo Raimund,

      nun schaut mein Ergebnis so aus:

      wenn das hier immer wieder ausgeführt werden soll

      SELECT *
      FROM   calendar
      WHERE  date BETWEEN '2012-01-16' AND DATE_ADD('2012-01-16', INTERVAL 13 DAY)

        
      und Du damit den Datumsbereich vom aktuellen Datum plus maximal 13 Tage begrenzen willst, dann ist es besser Du arbeitest mit der Funktion [CURDATE()](http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_curdate) (oder einem ihrer Synonyme):  
        
      Weiterhin kann man, wie Du unter [DATE_ADD](http://dev.mysql.com/doc/refman/5.0/en/date-and-time-functions.html#function_date-add) nachlesen kannst, Datumsarithmetik ganz nett im Klartext schreiben und somit kämst Du, falls ich Dich richtig verstanden habe, zu  
        
      ~~~sql
      SELECT  
          <spaltenliste>  
      FROM  
          calendar  
      WHERE  
          `date`  
      BETWEEN  
          CURDATE()                    -- dem aktuellen Datum  
      AND  
          CURDATE() + INTERVAL 13 DAY  -- und dem aktuellen Datum plus 13 Tage  
                                       -- Grenzen eingeschlossen
      

      Dieses Statement kannst Du nun jeden Tag nutzen, ohne es anpassen zu müssen.

      Freundliche Grüße

      Vinzenz

    3. SELECT *
      FROM   calendar
      WHERE  date BETWEEN '2012-01-01' AND DATE_SUB(DATE_ADD('2012-01-01', INTERVAL 1 MONTH), INTERVAL 1 DAY)

        
        
      Für deine erste Problemstellung ist wohl das Arbeiten mit YEAR() und MONTH() um einiges kürzer und verständlicher - und erfordert weit weniger Operationen.  
        
      Tag abziehen und Monat dazuzählen? Das versteht keiner beim ersten Hinschauen. Du willst doch alle Daten die sich mit dem gegebenen Jahr und Monat decken? Dann schreib es so oder wundere dich nicht, warum du in 3 Monaten nicht mehr weißt, was das eigentlich tut :)  
        
      `WHERE (YEAR(date) = YEAR(NOW()) AND MONTH(date) = MONTH(NOW()) -- aktuelles Datum`{:.language-sql}  
      `WHERE (YEAR(date) = 2012 AND MONTH(date) = 1) -- beliebers Datum`{:.language-sql}  
        
      
      > ~~~sql
        
      
      > SELECT *  
      > FROM   `calendar`  
      > WHERE  `date` BETWEEN '2012-01-16' AND DATE_ADD('2012-01-16', INTERVAL 13 DAY)  
      > 
      
      

      Wenn es dir um "heute + 13 Tage" geht, ist NOW() jedenfalls besser als das Datum manuell hinzufrickeln.

      Und auch wenn Tom sagt, DATE_ADD() wäre besser geeignet - ich meine dennoch, dass DATEDIFF() eleganter - und vor allem kürzer - ist, sofern es um Tage geht. Mit anderen Einheiten stößt man mit DATEDIFF() auf taube Ohren.

      WHERE DATEDIFF(date, NOW()) < 14 -- vom aktuellen Tag
      WHERE DATEDIFF(date, '2012-01-01') < 14 -- von einem beliebigen Tag an

      ich hoffe das ist nun der Beste Lösungsweg :)

      Das kommt drauf an, wie du das definierst:

      1. Performance?
        Benchmarken

      2. Verständlichkeit
        Das erste ist wenig nachvollziehbar, beim zweiten sehe ich keine Probleme

      3. Codelänge
        Da gibts sicher einsparungspotential

      4 Selbst erarbeitet
      Was gibt es schöneres? :)

      1. Nachtrag:

        Vinzenz Mai hat in jedem Fall recht: CURDATE() ist besser geeignet als NOW(), da hier ja nur das Datum und nicht Datum + Zeit benötigt wird (es sei denn, es geht dir im die Code-Länge des Statements :p).