Announcement

Collapse
No announcement yet.

Problem bei Jahrvergleichen "Trunc(SYSDATE, 'YYYY')"

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Problem bei Jahrvergleichen "Trunc(SYSDATE, 'YYYY')"

    Hallo.<br>

    Habe da ein kleines Problem unter Oracle. Bin absoluter Anfänger was Oracle betrifft.
    Habe hier ein bestehende Tabelle <i>xyz</i> und in dieser das Feld <i>datvon</i> vom Typ DATE.<br>
    Würde mir jetzt gerne alle Datumswerte ausgeben lassen, die "größergleich" dem aktuellen Jahr -1 sind.
    Habe mir gedacht man könnte das ganze so schreiben:
    <pre>select * from xyz where TRUNC(xyz.datvon, 'YYYY') >= TRUNC(SYSDATE, 'YYYY')-1</pre>
    Dies scheint nicht richtig zu funktionieren oder es ist nicht so angedacht. Kann mir da vielleicht jemand helfen?<br>

    MfG,

    Delphi Greenhorn

  • #2
    Versuchs mal mit
    select * from xyz where to_char(xyz.datvon, 'YYYY') >= to_char(SYSDATE-365, 'YYYY')-

    Comment


    • #3
      Hallo Feanor.

      Kann Oracle zwei Charwerte mit >= vergleichen?
      Ich habe bei mir jetzt mal <pre>to_number(to_char(xyz.datvon, 'yyyy') >= to_number(to_char(sysdate, 'yyyy'))-1</pre> probiert.
      Das ganze scheint auch zu funktionieren. Bei der Variante mit sysdate-365 habe ich ein ungutes Gefühl (Schaltjahr?).
      Aber mir gefällt diese to_number(to_char... Geschichte einfach nicht. Gibt es bei Oracle wirklich nichts, was mir einfach so das Jahr zurückliefert?? (z.B. Year() unter Informix)

      Ich verstehe dieses "Oracle-Kauderwelsch" einfach nicht.

      MfG,

      Delphi Greenhor

      Comment


      • #4
        Ja, Number ist in dem Fall wohl geschickter als Char.
        Ich kenne keine Funktion, die direkt das Jahr aus einem Datum extrahiert. Vielleicht kann man das aber geschickt mit einer PL/SQL-Funktion lösen

        Comment


        • #5
          Hallo Greenhorn

          Unter Oracle können Datumswerte als Float behandelt werden. D.h. es funktionieren prinzipiell Subtraktion und Addition. Ganzzahlige Werte sind dabei Tage - der gebrochene Anteil stellt Stunden, Minuten und Sekunden dar. TRUNC(SYSDATE, 'YYYY')-1 liefert heute also den 31.12.2003. Du müsstes also um ein "ganzes Jahr" abzuziehen 365 o. 366 (je nach Schaltjahr) subtrahieren. Um das mit den Schaltjahren ewas zu vereinfachen gibt es die Funktion ADD_MONTHS. Ein ADD_MONTHS(TRUNC(SYSDATE, 'YYYY'), -12) liefert (egal ob Schaltjahr oder nicht) immer den 01.01. des vorigen Jahres.

          Gruß Falk

          P.S.
          Der gebrochene Anteil eines Datums gliedert sich wie folgt:
          1/24 - 1 Stunde
          1/24/60 - 1 Minute
          1/24/60/60 - 1 Sekund
          Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

          Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

          Comment


          • #6
            Hallo Falk,

            danke für die Informationen. Muss mal den Vorschlag mit ADD_Months durchprobieren.

            <pre>to_number(to_char(sysdate, 'yyyy'))-1</pre>
            Mit dem Statement müsste ich doch auch Schaltjahrsicher sein, oder?

            MfG,

            Delphi Greenhor

            Comment


            • #7
              Hallo,

              wenn du zum Vergleichen kein Datum benötigst dann ist die Variante to_number(to_char(sysdate, 'yyyy'))-1 natürlich genauso geeignet und auch Schaltjahrsicher. Du mußt dabei aber sowohl den "Parameter" als auch den Wert des jeweiligen DS umrechnen um Vergleichen zu können. Dies wird spätestens bei der Frage der Performance interessant.
              z.B.<pre>
              ...where to_number(to_char(sysdate, 'yyyy'))-1 > to_number(to_char(table.datefield, 'yyyy'))
              und
              ...where add_months(trunc(sysdate, 'YYYY'), -12) > table.datefield</pre>
              liefern prinzipiell das gleiche Ergebnis und sind von der Logik her identisch. Aber: Ist die Tabelle "table" sehr groß und liegt auf dem Feld "datefield" ein Index, dann kann ORACLE diesen Index im 1.Fall <b>nicht</b> verwenden, im Fall 2 hingegen schon. Du wirst also einige Unterschiede in der Abfragegeschwindigkeit haben.

              Gruß Fal
              Wenn du denkst du hast alle Bugs gefunden, dann ist das ein Bug in deiner Denksoftware.

              Quellcode ohne ein Mindestmaß an Formatierung sehe ich mir nicht an! Ich leiste keinen Privatsupport per Mail oder PN!

              Comment


              • #8
                hallo greenhorn,

                heute ist z.b. der 11.06.2004, und du willst die einträge zwischen 12.06.2003 und heute, dann ist

                <pre>
                TRUNC(xyz.datvon) >= add_months(trunc(sysdate)+1,-12)
                </pre>

                wie von falk vorgeschlagen der richtige weg. dein o.a. vorschlag

                <pre>
                to_number(to_char(xyz.datvon, 'yyyy')) >= to_number(to_char(sysdate, 'yyyy'))-1
                </pre>

                liefert dir die einträge vom 1.1.2003 bis 11.06.2004 und das ist wohl nicht gewünscht, oder?

                gruss volke

                Comment


                • #9
                  Hallo Volker,

                  ich bräuchte alle Einträge, die im vergangenen Jahr liegen und alle Einträge die evtl. neuer als das vergangene Jahr sind.

                  @all Danke für die Hilfe. Ohne euch wäre ich verzweifelt :-)

                  Gruß,

                  Delphi Greenhor

                  Comment


                  • #10
                    Hi,

                    also seit Oracle 9i gibt es noch eine möglichkeit die einzelnen elemente des jahres zu extrahieren, mit hilfe der funktion EXTRACT.

                    syntax:
                    SELECT EXTRACT ([YEAR] [MONTH] [DAY] [HOUR] [MINUTE] [SECOND] FROM datums_wert) FROM tab;

                    bsp:
                    SELECT EXTRACT (YEAR FROM SYSDATE) FROM DUAL;

                    somit könntest du für dein beispiel auch schreiben

                    SELECT *
                    FROM xyz
                    WHERE EXTRACT (YEAR FROM xyz.datfeld) &gt=
                    (EXTRACT (YEAR FROM SYSDATE)-1);

                    c

                    Comment

                    Working...
                    X