Announcement

Collapse
No announcement yet.

KW in Datum

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

  • KW in Datum

    hallo ich habe eine int- feld mit dem Aufbau 'YYYYKW' Beispiel 201321 (KW = Kalenderwoche). Daraus möchte ich jetzt ein Datum machen, jeweils den ersten Tag der KW. Beispiel aus 201321 soll werden 20.05.2013 (punkte nur zur besseren Lesbarkeit)kann mir jemand helfen?

    ich verzweifle noch bei der Aufgabe muss doch irgendwie gehen

  • #2
    Sieht schlecht aus, gemäss Dokumentation (siehe Datetime Format Elements) kann man von der Woche nicht auf das Datum umrechnen - Specify in TO_* datetime functions? -> No

    Vermutlich bleibt dir keine andere Möglichkeit als die Funktion selber zu schreiben.

    Gruss

    Comment


    • #3
      Originally posted by deathdragon View Post
      ich verzweifle noch bei der Aufgabe muss doch irgendwie gehen
      geht auch irgendwie, z.B. so -offset je nach Wochenanfang ändern:
      [HIGHLIGHT=SQL]
      WITH kwdatum AS
      (select 2013 jahr, 21 woche from dual union all
      select 2013 jahr, 39 woche from dual union all
      select 2013 jahr, 1 woche from dual union all
      select 2013 jahr, 53 woche from dual union all
      select 2013 jahr, 54 woche from dual union all
      select 2014 jahr, 1 woche from dual)
      SELECT Jahr, Woche,
      to_date('0101' || jahr, 'DDMMYYYY') + (7 * (woche - 1)) - 1 as UmrechnungMitTag,
      to_char(to_date('0101' || jahr, 'DDMMYYYY') + (7 * (woche - 1)) - 1, 'YYYYIW') as GegenprobeAufKW,
      to_char(to_date('0101' || jahr, 'DDMMYYYY') + (7 * (woche - 1)) - 1, 'YYYY.MM.DD Day') as GegenprobeLang
      FROM kwdatum;
      [/HIGHLIGHT]
      Müsste so auch unabhängig von NLS Settings sein.
      Gruß, defo

      Comment


      • #4
        Originally posted by defo View Post
        [HIGHLIGHT=SQL]
        WITH kwdatum AS
        (select 2013 jahr, 21 woche from dual union all
        select 2013 jahr, 39 woche from dual union all
        select 2013 jahr, 1 woche from dual union all
        select 2013 jahr, 53 woche from dual union all
        select 2013 jahr, 54 woche from dual union all
        select 2014 jahr, 1 woche from dual)
        SELECT Jahr, Woche,
        to_date('0101' || jahr, 'DDMMYYYY') + (7 * (woche - 1)) - 1 as UmrechnungMitTag,
        to_char(to_date('0101' || jahr, 'DDMMYYYY') + (7 * (woche - 1)) - 1, 'YYYYIW') as GegenprobeAufKW,
        to_char(to_date('0101' || jahr, 'DDMMYYYY') + (7 * (woche - 1)) - 1, 'YYYY.MM.DD Day') as GegenprobeLang
        FROM kwdatum;
        [/HIGHLIGHT]
        Das funktioniert aber nicht jedes Jahr, sondern nur wenn der erste Tag im Jahr ein Dienstag ist.

        Ich gehe mal davon aus, dass es die Kalenderwochen Definition nach ISO 8601 ist.
        Die Regeln stehen hier: http://de.wikipedia.org/wiki/Woche#Z..._nach_ISO_8601

        Ein wenig mehr musst du schon beachten.

        Gruss

        Comment


        • #5
          Originally posted by Wernfried View Post
          Das funktioniert aber nicht jedes Jahr, sondern nur wenn der erste Tag im Jahr ein Dienstag ist.
          Ein wenig mehr musst du schon beachten.
          Tja, Schlampen werden bestraft, sagte der Professor.
          Ich hab die Regeln jetzt nicht gelesen, statt dessen ein weiterer Versuch. Falls es wieder nicht ok ist > der TE muss ja auch noch was zu tun haben

          [highlight=sql]
          select x.*,
          --to_char(UmrechnungMitTag , 'YYYYIW') as Gegenprobe, -- das gibt einen grandiosen Fehler!
          jahr||to_char(UmrechnungMitTag , 'IW') as Gegenprobe, -- so ist besser
          to_char(UmrechnungMitTag , 'YYYY.MM.DD Day') AS GegenprobeLang
          from (
          select Jahr, Woche, Origdate ,
          next_day(Origdate+to_char(Origdate,'D')-1, 'MON')-7
          AS UmrechnungMitTag
          from (
          WITH kwdatum AS
          (SELECT 2007 jahr, 52 woche FROM dual UNION ALL
          SELECT 2008 jahr, 1 woche FROM dual UNION ALL
          SELECT 2008 jahr, 52 woche FROM dual UNION ALL
          SELECT 2009 jahr, 1 woche FROM dual UNION ALL
          SELECT 2009 jahr, 52 woche FROM dual UNION ALL
          SELECT 2010 jahr, 1 woche FROM dual UNION ALL
          SELECT 2010 jahr, 52 woche FROM dual UNION ALL
          SELECT 2011 jahr, 1 woche FROM dual UNION ALL
          SELECT 2011 jahr, 52 woche FROM dual UNION ALL
          SELECT 2012 jahr, 1 woche FROM dual UNION ALL
          SELECT 2012 jahr, 52 woche FROM dual UNION ALL
          SELECT 2013 jahr, 21 woche FROM dual UNION ALL
          SELECT 2013 jahr, 39 woche FROM dual UNION ALL
          SELECT 2013 jahr, 1 woche FROM dual UNION ALL
          SELECT 2013 jahr, 52 woche FROM dual UNION ALL
          SELECT 2014 jahr, 1 woche FROM dual UNION ALL
          SELECT 2013 jahr, 52 woche FROM dual UNION ALL
          SELECT 2014 jahr, 1 woche FROM dual UNION ALL
          SELECT 2013 jahr, 52 woche FROM dual UNION ALL
          SELECT 2014 jahr, 1 woche FROM dual UNION ALL
          SELECT 2013 jahr, 52 woche FROM dual UNION ALL
          SELECT 2014 jahr, 1 woche FROM dual UNION ALL
          SELECT 2013 jahr, 52 woche FROM dual UNION ALL
          SELECT 2014 jahr, 1 woche FROM dual)
          SELECT Jahr, Woche,
          to_date('0101' || jahr, 'DDMMYYYY') + (7 * (woche-1 )) as OrigDate
          FROM kwdatum))x;
          [/highlight]

          Es geht letztlich um:
          [highlight=sql] next_day(Origdate+to_char(Origdate,'D')-1, 'MON')-7 [/highlight]
          für Origdate gilt:
          [highlight=sql]..to_date('0101' || jahr, 'DDMMYYYY') + (7 * (woche-1 )) as OrigDate..[/highlight]

          Nicht schön, aber selten.
          Wer hat Lust den Fehler nachzuschlagen? Ist es wirklich einer? Vermutlich ist die Formatmaske in Kombi mit Jahr nicht definiert.
          Gruß, defo

          Comment


          • #6
            Das Jahr kann (gemäss ISO/DIN) auch 53 Wochen haben und manchmal ist der erste Tag der KW im alten Jahr.

            [highlight=sql]
            SELECT DISTINCT
            Jahr,
            TO_CHAR(TO_DATE(Jahr||'-01-01', 'yyyy-mm-dd') + Tag, 'IW') AS Woche,
            TRUNC(TO_DATE(Jahr||'-01-01', 'yyyy-mm-dd') + Tag, 'IW') AS erster_tag_der_woche
            FROM
            (SELECT LEVEL AS Jahr FROM dual WHERE LEVEL >= 1990 CONNECT BY LEVEL <= 2015)
            CROSS JOIN
            (SELECT LEVEL -10 AS Tag FROM dual CONNECT BY LEVEL <= 20)
            ORDER BY 3
            [/highlight]


            Code:
            JAHR	WOCHE	ERSTER_TAG_DER_WOCHE
            ================================
            1990	51	18.12.1989
            1990	52	25.12.1989
            1990	01	01.01.1990
            1990	02	08.01.1990
            1991	51	17.12.1990
            1991	52	24.12.1990
            1991	01	31.12.1990
            1991	02	07.01.1991
            1992	52	23.12.1991
            1992	01	30.12.1991
            1992	02	06.01.1992
            1993	52	21.12.1992
            1993	53	28.12.1992
            1993	01	04.01.1993
            1993	02	11.01.1993
            1994	51	20.12.1993
            1994	52	27.12.1993
            1994	01	03.01.1994
            1994	02	10.01.1994
            1995	51	19.12.1994
            1995	52	26.12.1994
            1995	01	02.01.1995
            1995	02	09.01.1995
            1996	51	18.12.1995
            1996	52	25.12.1995
            1996	01	01.01.1996
            1996	02	08.01.1996
            1997	52	23.12.1996
            1997	01	30.12.1996
            1997	02	06.01.1997
            1998	52	22.12.1997
            1998	01	29.12.1997
            1998	02	05.01.1998
            1999	52	21.12.1998
            1999	53	28.12.1998
            1999	01	04.01.1999
            1999	02	11.01.1999
            2000	51	20.12.1999
            2000	52	27.12.1999
            2000	01	03.01.2000
            2000	02	10.01.2000
            2001	51	18.12.2000
            2001	52	25.12.2000
            2001	01	01.01.2001
            2001	02	08.01.2001
            2002	51	17.12.2001
            2002	52	24.12.2001
            2002	01	31.12.2001
            2002	02	07.01.2002
            2003	52	23.12.2002
            2003	01	30.12.2002
            2003	02	06.01.2003
            2004	52	22.12.2003
            2004	01	29.12.2003
            2004	02	05.01.2004
            2005	52	20.12.2004
            2005	53	27.12.2004
            2005	01	03.01.2005
            2005	02	10.01.2005
            2006	51	19.12.2005
            2006	52	26.12.2005
            2006	01	02.01.2006
            2006	02	09.01.2006
            2007	51	18.12.2006
            2007	52	25.12.2006
            2007	01	01.01.2007
            2007	02	08.01.2007
            2008	51	17.12.2007
            2008	52	24.12.2007
            2008	01	31.12.2007
            2008	02	07.01.2008
            2009	52	22.12.2008
            2009	01	29.12.2008
            2009	02	05.01.2009
            2010	52	21.12.2009
            2010	53	28.12.2009
            2010	01	04.01.2010
            2010	02	11.01.2010
            2011	51	20.12.2010
            2011	52	27.12.2010
            2011	01	03.01.2011
            2011	02	10.01.2011
            2012	51	19.12.2011
            2012	52	26.12.2011
            2012	01	02.01.2012
            2012	02	09.01.2012
            2013	51	17.12.2012
            2013	52	24.12.2012
            2013	01	31.12.2012
            2013	02	07.01.2013
            2014	52	23.12.2013
            2014	01	30.12.2013
            2014	02	06.01.2014
            2015	52	22.12.2014
            2015	01	29.12.2014
            2015	02	05.01.2015
            Gruss
            Zuletzt editiert von Wernfried; 24.05.2013, 08:54. Reason: Bessere Beispieldaten

            Comment


            • #7
              Hallo Jungs danke erstmal für eure Hilfe aber leider hat mich bis jetzt noch nichts so richtig überzeugt. Das liegt eben an der Ungenauigkeit mal im alten Jahr mal im neuen. Später soll eine Selektion möglich sein und damit könnte es passieren das Datensätze herausfallen.

              aus der KW das Quartal machen würde mir auch schon etwas helfen aber genau da habe ich das gleiche Problem!

              Comment


              • #8
                Hallo,
                Ich hab kein Oracle hier zum testen, deshalb stell ich mal nur ein paar Gedankenspielchen an .
                Dein festes Format YYYYKW kannst du mit einfachen Stringfunktionen in Jahr und KW zerlegen. Den ersten Tag des ISO-KW-Jahres kannst du einfach ermitteln, indem du mit TO_DATE ein Datum (vorrangig in der MITTE des Jahres) aus dem gewünschten Jahr zusammenbaust und dieses mit TRUNC auf den ersten Tag des ISO-Jahres kürzt. Also etwa so:
                [highlight=sql]
                TRUNC(TO_DATE('0106' || dasJahr, 'DDMMYYYY'), 'IYYY')
                [/highlight]
                Jedes weitere Datum ist dann einfach nur dieses Datum + (gewünschteKW - 1) * 7 (jede Woche hat GENAU 7 Tage). Also z.B.:
                [highlight=sql]
                TRUNC(TO_DATE('0106' || dasJahr, 'DDMMYYYY'), 'IYYY') + (dieKW - 1) * 7
                [/highlight]

                Gruß Falk
                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


                • #9
                  Originally posted by Falk Prüfer View Post
                  [highlight=sql]
                  TRUNC(TO_DATE('0106' || dasJahr, 'DDMMYYYY'), 'IYYY') + (dieKW - 1) * 7
                  [/highlight]

                  Gruß Falk
                  Scheint zu funktionieren, das ISO-Jahr (Format 'IYYY') nimmt einem eine Menge Arbeit ab und erspart ein paar "CASE ... WHEN".
                  Hier mal ein Test Lauf:

                  [highlight=sql]
                  WITH t AS
                  (SELECT TO_DATE(lfd_Jahr||'-01-01', 'yyyy-mm-dd') + Tag AS datum
                  FROM
                  (SELECT LEVEL AS lfd_Jahr FROM dual WHERE LEVEL >= 1990 CONNECT BY LEVEL <= 2015)
                  CROSS JOIN
                  (SELECT LEVEL -10 AS Tag FROM dual CONNECT BY LEVEL <= 20)),
                  w AS
                  (SELECT datum, TO_CHAR(datum, 'IYYY') AS Jahr, TO_CHAR(datum, 'IW') AS Woche, TRUNC(datum, 'IW') AS erster_tag_der_woche
                  FROM t)
                  SELECT DISTINCT Jahr, Woche, erster_tag_der_woche,
                  TRUNC(TO_DATE('0106' || Jahr, 'DDMMYYYY'), 'IYYY') + (Woche - 1) * 7 AS datum_aus_woche
                  FROM w
                  ORDER BY 4
                  [/highlight]



                  Code:
                  JAHR	WOCHE	ERSTER_TAG_DER_WOCHE	DATUM_AUS_WOCHE
                  1989	51	18.12.1989	18.12.1989
                  1989	52	25.12.1989	25.12.1989
                  1990	01	01.01.1990	01.01.1990
                  1990	02	08.01.1990	08.01.1990
                  1990	51	17.12.1990	17.12.1990
                  1990	52	24.12.1990	24.12.1990
                  1991	01	31.12.1990	31.12.1990
                  1991	02	07.01.1991	07.01.1991
                  1991	52	23.12.1991	23.12.1991
                  1992	01	30.12.1991	30.12.1991
                  1992	02	06.01.1992	06.01.1992
                  1992	52	21.12.1992	21.12.1992
                  1992	53	28.12.1992	28.12.1992
                  1993	01	04.01.1993	04.01.1993
                  1993	02	11.01.1993	11.01.1993
                  1993	51	20.12.1993	20.12.1993
                  1993	52	27.12.1993	27.12.1993
                  1994	01	03.01.1994	03.01.1994
                  1994	02	10.01.1994	10.01.1994
                  1994	51	19.12.1994	19.12.1994
                  1994	52	26.12.1994	26.12.1994
                  1995	01	02.01.1995	02.01.1995
                  1995	02	09.01.1995	09.01.1995
                  1995	51	18.12.1995	18.12.1995
                  1995	52	25.12.1995	25.12.1995
                  1996	01	01.01.1996	01.01.1996
                  1996	02	08.01.1996	08.01.1996
                  1996	52	23.12.1996	23.12.1996
                  1997	01	30.12.1996	30.12.1996
                  1997	02	06.01.1997	06.01.1997
                  1997	52	22.12.1997	22.12.1997
                  1998	01	29.12.1997	29.12.1997
                  1998	02	05.01.1998	05.01.1998
                  1998	52	21.12.1998	21.12.1998
                  1998	53	28.12.1998	28.12.1998
                  1999	01	04.01.1999	04.01.1999
                  1999	02	11.01.1999	11.01.1999
                  1999	51	20.12.1999	20.12.1999
                  1999	52	27.12.1999	27.12.1999
                  2000	01	03.01.2000	03.01.2000
                  2000	02	10.01.2000	10.01.2000
                  2000	51	18.12.2000	18.12.2000
                  2000	52	25.12.2000	25.12.2000
                  2001	01	01.01.2001	01.01.2001
                  2001	02	08.01.2001	08.01.2001
                  2001	51	17.12.2001	17.12.2001
                  2001	52	24.12.2001	24.12.2001
                  2002	01	31.12.2001	31.12.2001
                  2002	02	07.01.2002	07.01.2002
                  2002	52	23.12.2002	23.12.2002
                  2003	01	30.12.2002	30.12.2002
                  2003	02	06.01.2003	06.01.2003
                  2003	52	22.12.2003	22.12.2003
                  2004	01	29.12.2003	29.12.2003
                  2004	02	05.01.2004	05.01.2004
                  2004	52	20.12.2004	20.12.2004
                  2004	53	27.12.2004	27.12.2004
                  2005	01	03.01.2005	03.01.2005
                  2005	02	10.01.2005	10.01.2005
                  2005	51	19.12.2005	19.12.2005
                  2005	52	26.12.2005	26.12.2005
                  2006	01	02.01.2006	02.01.2006
                  2006	02	09.01.2006	09.01.2006
                  2006	51	18.12.2006	18.12.2006
                  2006	52	25.12.2006	25.12.2006
                  2007	01	01.01.2007	01.01.2007
                  2007	02	08.01.2007	08.01.2007
                  2007	51	17.12.2007	17.12.2007
                  2007	52	24.12.2007	24.12.2007
                  2008	01	31.12.2007	31.12.2007
                  2008	02	07.01.2008	07.01.2008
                  2008	52	22.12.2008	22.12.2008
                  2009	01	29.12.2008	29.12.2008
                  2009	02	05.01.2009	05.01.2009
                  2009	52	21.12.2009	21.12.2009
                  2009	53	28.12.2009	28.12.2009
                  2010	01	04.01.2010	04.01.2010
                  2010	02	11.01.2010	11.01.2010
                  2010	51	20.12.2010	20.12.2010
                  2010	52	27.12.2010	27.12.2010
                  2011	01	03.01.2011	03.01.2011
                  2011	02	10.01.2011	10.01.2011
                  2011	51	19.12.2011	19.12.2011
                  2011	52	26.12.2011	26.12.2011
                  2012	01	02.01.2012	02.01.2012
                  2012	02	09.01.2012	09.01.2012
                  2012	51	17.12.2012	17.12.2012
                  2012	52	24.12.2012	24.12.2012
                  2013	01	31.12.2012	31.12.2012
                  2013	02	07.01.2013	07.01.2013
                  2013	52	23.12.2013	23.12.2013
                  2014	01	30.12.2013	30.12.2013
                  2014	02	06.01.2014	06.01.2014
                  2014	52	22.12.2014	22.12.2014
                  2015	01	29.12.2014	29.12.2014
                  2015	02	05.01.2015	05.01.2015
                  Gruss

                  Comment


                  • #10
                    wow das sieht ja sehr gut aus ABER die syntax übersteigt meine sql fähigkeiten! kann mir jemand erklären wie ich nun meine spalte auslesen kann um eben den wert zu erlangen? sehr nett wäre auch wenn mir noch jemand die syntax etwas erklären kann, wie gesagt das übersteigt meinen jetzigen wissensstand ich würde gern diese Syntax nutzen in der DB DATEN spalte datum-kw

                    danke für eure hilfe

                    Comment


                    • #11
                      [QUOTE=Wernfried;272725]

                      Keine Panik, mein Statement diente nur dazu Beispieldaten zu erzeugen um das Ganze testen zu können.

                      Alles was du brauchst, ist das Statement von Falk, du musst nur dein Datum auftrennen, z.B. so:
                      [highlight=sql]
                      TRUNC(TO_DATE('0106' || SUBSTR(datum_kw, 1,4), 'DDMMYYYY'), 'IYYY') + (SUBSTR(datum_kw, -2) - 1) * 7
                      [/highlight]


                      SUBSTR(datum_kw, 1,4) liefert die ersten vier Zeichen aus dem Datum String
                      SUBSTR(datum_kw, -2) liefert die letzen zwei Zeichen aus dem Datum String
                      TRUNC(TO_DATE('0106' || ..., 'DDMMYYYY'), 'IYYY') liefert den ersten Tag der 1. Kalenderwoche des Jahres (kann auch im vorherigen Jahr liegen, z.B. die 1. KW im Jahre 2013 geht vom 31.12.2012 bis 07.01.2013)
                      + (... - 1) * 7 addiert die Anzahl Wochen zum ersten Tag der 1. Kalenderwoche des Jahres

                      Gruss

                      Comment


                      • #12
                        Abfrage läuft nach ein paar wochen immernoch fehlerfrei danke an alle noch mal

                        Comment

                        Working...
                        X