Spalte mit Datumswerten immer um einen Monat erhöhen

ny_unity

SQL-Guru
Beiträge
195
Hallo zusammen,

ich bin gerade am überlegen, wie ich folgendes Problem lösen kann, eventuell gibt es ein paar Tipps.

Ich habe eine Spalte "Datum". Dieses beginnt in der ersten Zeile mit 01.01.2015. Ich möchte jetzt weitere Zeilen erstellen, bis ich zum heutigen Tag/Monat angekommen bin, also den 01.10.2018.

Die Werte in der Spalte "Datum" sollen sich immer um 1 Monat erhöhen, also:
01.01.2015
01.02.2015
01.03.2015
.
.
.
01.10.2018

Ich habe noch nie mit Schleifen gearbeitet... ist das hiermit möglich? Kann mir jemand ein einfaches Beispiel nennen? Würde es gern selbst lösen =)

Vielen Dank!

Erik
 
Werbung:
Mein Ergebnis lautet im Moment:
Datum
----------
2015-01-01
(1 Zeile betroffen)
Datum
----------
2015-02-01
(1 Zeile betroffen)
Datum
----------
2015-03-01
(1 Zeile betroffen)
Datum
----------
2015-04-01
(1 Zeile betroffen)
Datum
----------
2015-05-01
(1 Zeile betroffen)
Datum
----------
2015-06-01
(1 Zeile betroffen)
Datum
----------
2015-07-01
(1 Zeile betroffen)
Datum
----------
2015-08-01
(1 Zeile betroffen)
Datum
----------
2015-09-01
(1 Zeile betroffen)
Datum
----------
2015-10-01
(1 Zeile betroffen)
Datum
----------
2015-11-01
(1 Zeile betroffen)
Datum
----------
2015-12-01
(1 Zeile betroffen)
Datum
----------
2016-01-01
(1 Zeile betroffen)
Datum
----------
2016-02-01
(1 Zeile betroffen)
Datum
----------
2016-03-01
(1 Zeile betroffen)
Datum
----------
2016-04-01
(1 Zeile betroffen)
Datum
----------
2016-05-01
(1 Zeile betroffen)
Datum
----------
2016-06-01
(1 Zeile betroffen)
Datum
----------
2016-07-01
(1 Zeile betroffen)
Datum
----------
2016-08-01
(1 Zeile betroffen)
Datum
----------
2016-09-01
(1 Zeile betroffen)
Datum
----------
2016-10-01
(1 Zeile betroffen)
Datum
----------
2016-11-01
(1 Zeile betroffen)
Datum
----------
2016-12-01
(1 Zeile betroffen)
Datum
----------
2017-01-01
(1 Zeile betroffen)
Datum
----------
2017-02-01
(1 Zeile betroffen)
Datum
----------
2017-03-01
(1 Zeile betroffen)
Datum
----------
2017-04-01
(1 Zeile betroffen)
Datum
----------
2017-05-01
(1 Zeile betroffen)
Datum
----------
2017-06-01
(1 Zeile betroffen)
Datum
----------
2017-07-01
(1 Zeile betroffen)
Datum
----------
2017-08-01
(1 Zeile betroffen)
Datum
----------
2017-09-01
(1 Zeile betroffen)
Datum
----------
2017-10-01
(1 Zeile betroffen)
Datum
----------
2017-11-01
(1 Zeile betroffen)
Datum
----------
2017-12-01
(1 Zeile betroffen)
Datum
----------
2018-01-01
(1 Zeile betroffen)
Datum
----------
2018-02-01
(1 Zeile betroffen)
Datum
----------
2018-03-01
(1 Zeile betroffen)
Datum
----------
2018-04-01
(1 Zeile betroffen)
Datum
----------
2018-05-01
(1 Zeile betroffen)
Datum
----------
2018-06-01
(1 Zeile betroffen)
Datum
----------
2018-07-01
(1 Zeile betroffen)
Datum
----------
2018-08-01
(1 Zeile betroffen)
Datum
----------
2018-09-01
(1 Zeile betroffen)

folgenden code:
Code:
DECLARE @StartDate AS DATE
DECLARE @EndDate AS DATE
DECLARE @CurrentDate AS DATE
SET @StartDate = '2015-01-01'
SET @EndDate = DATEFROMPARTS(YEAR(CURRENT_TIMESTAMP),MONTH(CURRENT_TIMESTAMP),1)
SET @CurrentDate = @StartDate
WHILE (@CurrentDate < @EndDate)
BEGIN
   
    IF @@ROWCOUNT < 1
        SELECT @CurrentDate as Datum
    SET @CurrentDate = dateadd(MONTH,1, @CurrentDate); /*increment current date*/
END

Es sind jetzt immer neue Abfrageergebnisse, kann ich das zu einem zusammenfassen?
 
Hab es gelöst, für alle, die wissen wollen wie:

Code:
DECLARE @StartDate AS DATE
DECLARE @EndDate AS DATE
DECLARE @CurrentDate AS DATE
DECLARE @PARAMETER TABLE (datum DATE)
SET @StartDate = '2015-01-01'
SET @EndDate = DATEFROMPARTS(YEAR(CURRENT_TIMESTAMP),MONTH(CURRENT_TIMESTAMP),1)
SET @CurrentDate = @StartDate
WHILE (@CurrentDate < @EndDate)
BEGIN
    IF @@ROWCOUNT < 1
        INSERT INTO @PARAMETER 
        VALUES (@CurrentDate)
    SET @CurrentDate = dateadd(MONTH,1, @CurrentDate); /*increment current date*/
END
SELECT * FROM @PARAMETER
 
Oder eleganter:
Code:
WITH PARAMETER(datum) AS (
   SELECT   convert(DATE,'2015-01-01')
   UNION ALL
   SELECT   dateadd(month,1,datum)
   FROM   PARAMETER
   WHERE   dateadd(month,1,datum) < getdate()
   )
SELECT   *
FROM   PARAMETER
 
looooooooooooooooooooooooooooooooooooooooooooooooooooooooooooool

Aufgrund deiner Anpassung ist meine Zeit für die Ausführung auf 0 gegangen.... Im Zusammenhang mit deiner anderen Hilfe mit
Code:
0 + sum(e.WS_ein-a.WS_aus) over (order by e.startdatum) AS WS_stand

Was die Schleife so ausmacht :)

Danke @ukulele !
 
@ukulele das ganze klappt aber nicht mehr im Firebird SQL order? Da macht er nur einen Datensatz dazu, nicht alle bis heute...

Code:
SELECT * FROM
(
WITH parm AS
    (
    SELECT TIMESTAMP '2015-01-01' AS startdatum, DATEADD(DAY,-1, (DATEADD(MONTH, 1, TIMESTAMP '2015-01-01'))) AS endedatum
    FROM RDB$DATABASE
    )
, parame AS
    (
    SELECT startdatum, endedatum
    FROM parm
    UNION ALL
    SELECT   dateadd(month,1,startdatum) AS startdatum, DATEADD(DAY, -1, (DATEADD(MONTH, 1, dateadd(month,1,startdatum)))) AS endedatum
    FROM   parm
    WHERE (dateadd(month,1,startdatum) <= TIMESTAMP 'TODAY')
    )
SELECT * FROM parame
)
 
Ich glaube Firebird SQL beherscht kein CTE, bin aber nicht sicher.

Dein Code ist aber auch falsch, WITH muss immer an erster Stelle stehen und kann nicht erst in einem Subselct aufgerufen werden. Der SELECT * FROM ( ) ist auch komplett überflüssig denn du hast ja schon einen SELECT * FROM parame. Außerdem muss dein Subselect einen Namen haben, hinter der Klammer fehlt also noch was.
 
Code:
WITH parm AS
    (
    SELECT TIMESTAMP '2015-01-01' AS startdatum, DATEADD(DAY,-1, (DATEADD(MONTH, 1, TIMESTAMP '2015-01-01'))) AS endedatum
    FROM RDB$DATABASE
    )
, parame AS
    (
    SELECT startdatum, endedatum
    FROM parm
    UNION ALL
    SELECT   dateadd(month,1,startdatum) AS startdatum, DATEADD(DAY, -1, (DATEADD(MONTH, 1, dateadd(month,1,startdatum)))) AS endedatum
    FROM   parm
    WHERE dateadd(month,1,startdatum) <= TIMESTAMP 'TODAY'
    )
SELECT * FROM parame
funktioniert, wirft aber keine Ergebnisse aus.

Code:
SELECT * FROM
(
WITH parm AS
    (
    SELECT TIMESTAMP '2015-01-01' AS startdatum, DATEADD(DAY,-1, (DATEADD(MONTH, 1, TIMESTAMP '2015-01-01'))) AS endedatum
    FROM RDB$DATABASE
    )
, parame AS
    (
    SELECT startdatum, endedatum
    FROM parm
    UNION ALL
    SELECT   dateadd(month,1,startdatum) AS startdatum, DATEADD(DAY, -1, (DATEADD(MONTH, 1, dateadd(month,1,startdatum)))) AS endedatum
    FROM   parm
    WHERE dateadd(month,1,startdatum) <= TIMESTAMP 'TODAY'
    )
SELECT * FROM parame
) t1
Wirft wieder nur zwei ergebnisse aus, den 01.01.2015 und 01.02.2015. WAs ist denn das CTE

*edit*

common tables expression, also die normalen WITH tables.. das klappt im Firebrird, aber nicht die Aufzählung wie im MSSQL, alle Monate bis heute
 
Zuletzt bearbeitet:
Ich habe echt noch nie Firebird benutzt :)

SELECT
Description: A common table expression or CTE can be described as a virtual table or view, defined in a preamble to a main query, and going out of scope after the main query's execution. The main query can reference any CTEs defined in the preamble as if they were regular tables or views. CTEs can be recursive, i.e. self-referencing, but they cannot be nested.
Es gibt da noch WITH RECURSIVE als Schlüsselwort, siehe Beispiel.

Allerdings scheint mir dein Code noch einen Fehler zu haben. Die CTE "parame" müsste auf sich selbst referenzieren, du machst aber einen UNION zwischen zwei Selects auf param. Der zweite Select muss auf parame, also sich selbst, referenzieren.
Code:
    SELECT startdatum, endedatum
    FROM parm
    UNION ALL
    SELECT   dateadd(month,1,startdatum) AS startdatum, DATEADD(DAY, -1, (DATEADD(MONTH, 1, dateadd(month,1,startdatum)))) AS endedatum
    FROM   parme
    WHERE dateadd(month,1,startdatum) <= TIMESTAMP 'TODAY'
 
Dynamic SQL Error
SQL error code = -104
CTE 'PARME' has cyclic dependencies (Database)
Code:
WITH parm AS 
    (
    SELECT  TIMESTAMP '2015-01-01' AS datum FROM RDB$DATABASE
    )
, parme AS
    (
    SELECT datum
    FROM parm
    UNION ALL
    SELECT   dateadd(month,1,datum) AS datum, DATEADD(DAY, -1, (DATEADD(MONTH, 1, dateadd(month,1,datum)))) AS endedatum
    FROM   parme
    WHERE dateadd(month,1,datum) <= TIMESTAMP 'TODAY'
    )
SELECT * FROM parme

Ich glaub Firebird kann nicht auf sich selbst abfragen
 
Laut Zitat kann CTE rekursiv sein. Teste doch mal
Code:
WITH RECURSIVE parme AS
    (
    SELECT  TIMESTAMP '2015-01-01' AS datum FROM RDB$DATABASE
    UNION ALL
    SELECT   dateadd(month,1,startdatum) AS datum, DATEADD(DAY, -1, (DATEADD(MONTH, 1, dateadd(month,1,datum)))) AS endedatum
    FROM   parme
    WHERE dateadd(month,1,datum) <= TIMESTAMP 'TODAY'
    )
SELECT * FROM parme
 
in der Tat, der code von ukulele ist nicht ganz korrekt, aber so gehts:

Code:
SELECT * FROM
(
WITH RECURSIVE parme AS
    (
    SELECT  TIMESTAMP '2015-01-01' AS datum, TIMESTAMP '2015-01-31' as endedatum FROM RDB$DATABASE
    UNION ALL
    SELECT   dateadd(month,1,datum) AS datum, DATEADD(DAY, -1, (DATEADD(MONTH, 1, dateadd(month,1,datum)))) AS endedatum
    FROM   parme
    WHERE dateadd(month,1,datum) <= TIMESTAMP 'TODAY'
    )
SELECT * FROM parme)

jetzt habe ich extra nochmal VPN angemacht :-D

Danke für die Hilfe, schönes Wochenende!
 
Werbung:
Korrekt ist dehnbar, unter MSSQL wäre das mit dem WITH im Subselect nicht lauffähig. Das finde ich schon recht ungewöhnlich, auch für Firebird. Hauptsache es läuft...
 
Zurück
Oben