Mehrere Ergebnisse aus einem Datensatz (Jahresangaben)

gollum

Neuer Benutzer
Beiträge
2
Guten Abend!

Als sporadischer MS-SQL-Nutzer stehe ich vor folgendem Problem.

a) Struktur der Ausgangsdaten

ID Data VON BIS
2001 xyz 1998 2001
2002 dfg 2014 2015
2003 jkl 2013

Die Tabelle enthält Fahrzeugdaten mit Baujahresangaben. Leere "BIS"-Felder sind durch das aktuelle Jahr zu ersetzen (klass. ISNULL-Funktion).

b) Für eine externe Anwendung wird eine Ausgabetabelle pro Baujahr in folgender Form benötigt:

ID DATA YEAR
2001 xyz 1998
2001 xyz 1999
2001 xyz 2000
2001 xyz 2001
2002 dfg 2014
2002 dfg 2015
2003 jkl 2013
2003 jkl 2014
2003 jkl 2015
2003 jkl 2016

D. h. die Von-Bis-Angaben der Ausgangstabelle sollen im SELECT als Datensatz pro Baujahr ausgegeben werden.
In SQL beiße ich mir die Zähne aus, mir fehlt bereits ein Ansatz. Jeder Hinweis zur Vorgehensweise ist willkommen.
 
Werbung:
Code:
test=*# select * from gollum ;
  id  | data | von  | bis  
------+------+------+------
 2001 | xyz  | 1998 | 2001
 2002 | dfg  | 2014 | 2015
 2003 | jkl  | 2013 |   
(3 rows)

test=*# select * from gollum left join generate_series(gollum.von, coalesce(gollum.bis, extract(year from current_date)::int)) g on (true);
  id  | data | von  | bis  |  g   
------+------+------+------+------
 2001 | xyz  | 1998 | 2001 | 1998
 2001 | xyz  | 1998 | 2001 | 1999
 2001 | xyz  | 1998 | 2001 | 2000
 2001 | xyz  | 1998 | 2001 | 2001
 2002 | dfg  | 2014 | 2015 | 2014
 2002 | dfg  | 2014 | 2015 | 2015
 2003 | jkl  | 2013 |  | 2013
 2003 | jkl  | 2013 |  | 2014
 2003 | jkl  | 2013 |  | 2015
 2003 | jkl  | 2013 |  | 2016
(10 rows)

test=*#

select 'gute Nacht';
 
Zunächst: Danke.

Da ich auf einem MS-SQL -Server arbeite, werde ich mir die PostgreSQL-Lösung über eine StoredFunction nachbauen müssen. Den Ansatz dazu habe ich aber ebenfalls gefunden und habe nun einen Weg.
 
Werbung:
Das läßt sich auch ohne SP lösen:
Code:
WITH tabelle(id,data,von,bis) AS (
   SELECT   2001,'xyz',1998,2001
   ), t(id,data,jahr) AS (
   SELECT   tabelle.id,
       tabelle.data,
       tabelle.von
   FROM   tabelle
   UNION ALL
   SELECT   t.id,
       t.data,
       t.jahr + 1
   FROM   t
   INNER JOIN tabelle
   ON     t.id = tabelle.id
   WHERE   tabelle.bis >= t.jahr + 1
   )
SELECT   t.*
FROM   t
In dem Beispiel erzeuge ich zunächst die eigentliche Tabelle, bei dir müsste das kürzer ausfallen:
Code:
WITH t(id,data,jahr) AS (
   SELECT   tabelle.id,
       tabelle.data,
       tabelle.von
   FROM   tabelle
   UNION ALL
   SELECT   t.id,
       t.data,
       t.jahr + 1
   FROM   t
   INNER JOIN tabelle
   ON     t.id = tabelle.id
   WHERE   tabelle.bis >= t.jahr + 1
   )
SELECT   t.*
FROM   t
 
Zurück
Oben