none
In eine Tabelle Zeilen einfügen

    Frage

  • Ich habe eine Tabelle die nach Personen sortiert ist.
    Ein Beispiel:
    Das hier ist meine Ausgangstabelle:

    Personen         Jahr             Gehalt
    Eric                 2011            50000
    Eric                 2015            60000
    Luise               2014            40000
    Luise               2017            45000

    und diese Tabelle möchte ich haben:

    Personen         Jahr             Gehalt
    Eric                 2011            50000
    Eric                 2012            50000
    Eric                 2013            50000
    Eric                 2014            50000
    Eric                 2015            60000
    Eric                 2016            60000
    Eric                 2017            60000
    Luise               2014            40000
    Luise               2015            40000
    Luise               2016            40000
    Luise               2017            45000

    Meine Frage ist kann mir jemand helfen, wie ich diese Ergebnis erreiche? bzw. Kennt jemand ein Skript das ich verwenden kann um mein Problem zu lösen?

    Ich sitze wirklich schon sehr lange an diesem Problem.
    Ich bin um jede Antwort dankbar.
    Viele Grüße Lara

    Montag, 5. Februar 2018 14:28

Alle Antworten

  • Um Daten der Tabelle hinzuzufügen benötigst du den Insert-Befehl.
    Die Sortierung gibst du beim Select-Befehl mit "Order by" an.

    Eine Tabelle hat per Default keine Sortierung. Die Standardausgabe ist i.d.R. die sog. Eingangsfolge, also wie die Daten in die Tabelle gekommen sind.

    Montag, 5. Februar 2018 17:49
  • Ich muss ein bisschen raten was genau deine Anforderungen sind. Ich vermute mal dass die fehlenden Jahresgehälter für jede Person ab ihrem jeweiligen ersten Jahr mit den Werten aus dem jeweils vorigem Jahr aufgefüllt werden sollen.

    Ob bzw. wie man das in einen Select packen könnte wüsste ich auch nicht, aber als halbwegs prozedural programmiertes Skript geht das ganz gut:

    declare @personen table (Personen nvarchar(max), Jahr int, Gehalt int);
    insert into @personen values
    	('Eric', 2011, 50000), ('Eric', 2015, 50000),
    	('Luise', 2014, 50000), ('Luise', 2017, 50000);
    
    
    declare @jahr int = (select min(Jahr) from @personen);
    declare @maxJahr int = 2017;
    
    while @jahr <= @maxJahr
    begin
    	
    	insert into @personen
    	select p1.Personen, @jahr Jahr, 
    		(select p3.Gehalt from @personen p3 where p3.Personen = p1.Personen and p3.Jahr = 
    			(select max(p2.Jahr) from @personen p2 where p2.Personen = p1.Personen and p2.Jahr <= @jahr)) Gehalt
    	 from (select distinct Personen from @personen) p1
    	 where exists (select * from @personen p4 where p4.Personen = p1.Personen and p4.Jahr <= @jahr) and
               not exists (select * from @personen p5 where p5.Personen = p1.Personen and p5.Jahr = @jahr);
    
    	set @jahr = @jahr + 1;
    
    end

    Das Skript geht jedes Jahr durch. Im Select wird für jede Person ermittelt, ob es ein "vorheriges" Gehalt gibt, aber kein Gehalt zum aktuellem Jahr und dann ggf. eine Zeile erzeugt mit dem letzten vorhandenem Jahrgehalt.

    Montag, 5. Februar 2018 22:38
  • Ich hab gerade noch ein bisschen rumprobiert und mit einem kleinen Trick kriegt man es auch ohne Schleife hin:

    declare @zahlen table (Zahl int);
    insert into @zahlen values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
    
    insert into @personen
    select p1.Personen, j.Jahr, 
    	(select p3.Gehalt from @personen p3 where p3.Personen = p1.Personen and p3.Jahr = 
    		(select max(p2.Jahr) from @personen p2 where p2.Personen = p1.Personen and p2.Jahr <= j.Jahr)) Gehalt
    from (select (2000 + z1.Zahl + z2.Zahl * 10) Jahr from @zahlen z1, @zahlen z2) j,
    	 (select distinct Personen from @personen) p1
    where j.Jahr <= 2017 and
    	  exists (select * from @personen p4 where p4.Personen = p1.Personen and p4.Jahr <= j.Jahr) and
          not exists (select * from @personen p5 where p5.Personen = p1.Personen and p5.Jahr = j.Jahr);

    Und falls du eigentlich die Original-Tabelle nicht verändern und nur eine vollständige Ergebnis-Tabelle wolltest, sähe es so aus: 

    declare @zahlen table (Zahl int);
    insert into @zahlen values (0), (1), (2), (3), (4), (5), (6), (7), (8), (9);
    
    select p1.Personen, j.Jahr, 
    	(select p3.Gehalt from @personen p3 where p3.Personen = p1.Personen and p3.Jahr = 
    		(select max(p2.Jahr) from @personen p2 where p2.Personen = p1.Personen and p2.Jahr <= j.Jahr)) Gehalt
    from (select (2000 + z1.Zahl + z2.Zahl * 10) Jahr from @zahlen z1, @zahlen z2) j,
    	 (select distinct Personen from @personen) p1
    where j.Jahr <= 2017 and
    	  exists (select * from @personen p4 where p4.Personen = p1.Personen and p4.Jahr <= j.Jahr);

    PS: Diese Skripte funktionieren nur für die Jahre 2000-2099. Falls du einen anderen Bereich brauchst musst du den @zahlen-Select noch ein bisschen anpassen.
    Montag, 5. Februar 2018 22:57
  • Hallo Lara,

    Wenn Du die Daten nicht zwingend persistieren willst, kannst Du es einfach on-the-fly abfragen:

    ;WITH jahre AS
      (SELECT 2011 AS Jahr
       UNION ALL
       SELECT Jahr + 1 AS Jahr
       FROM jahre
       WHERE Jahr < DATEPART(year, GETDATE()))
    
    , gehaelter AS
       (SELECT 'Eric' AS Person, 2011 AS Jahr, 50000 AS Gehalt UNION ALL
        SELECT 'Eric', 2015, 60000 UNION ALL
        SELECT 'Luise', 2014, 40000 UNION ALL
        SELECT 'Luise', 2017, 45000)
    
    , mitarbeiter AS
       (SELECT DISTINCT Person
        FROM gehaelter)    
    
    SELECT M.Person,
           J.Jahr,
           (SELECT TOP 1 G.Gehalt
            FROM gehaelter AS G
            WHERE G.Person = M.Person
                  AND G.Jahr <= J.Jahr
            ORDER BY G.Jahr DESC) AS Gehalt         
    FROM jahre AS J
         CROSS JOIN
         mitarbeiter AS M
    ORDER BY M.Person,
             J.Jahr;


    Olaf Helper

    [ Blog] [ Xing] [ MVP]

    Dienstag, 6. Februar 2018 06:58
  • Hallo

    ich hab mittlerweile dein Skript mal ausprobiert, leider hat es nicht funktioniert.
    Es ist zwar Fehlerfrei durchgelaufen, aber ich habe als Rückmeldung bekommen das 0 Zeilen betroffen sind.
    Ich hab es auf einen anderen Anwendungsfall übertragen.
    Das Skript sollte so dynamisch wie möglich bleiben.

    Hier ist mein Skript:

    GO


    declare@jahrint=(selectYear(min([dbo].TB_Urlaubsanspruch_Test.jahr))from[dbo].TB_Urlaubsanspruch_Test);

    declare@maxjahrint=(Year(GetDate()));


    while@jahr<=@maxjahr


    begin

    insertinto[dbo].TB_Urlaubsanspruch_Test2


    selectu1.mitarbeiternr,@jahrjahr,


    (selectu3.urlaubsanspruchfrom[dbo].TB_Urlaubsanspruch_Testu3whereu3.mitarbeiternr=u1.mitarbeiternrandu3.jahr=


    (selectmax(u2.jahr)from[dbo].TB_Urlaubsanspruch_Testu2whereu2.mitarbeiternr=u1.mitarbeiternrandu2.jahr<=@jahr))urlaubsanspruch


    from (selectdistinctmitarbeiternrfrom  [dbo].TB_Urlaubsanspruch_Test)u1


    whereexists(selectmitarbeiternr,jahr,urlaubsanspruchfrom[dbo].TB_Urlaubsanspruch_Testu4whereu4.mitarbeiternr=u1.mitarbeiternrandu4.jahr<=@jahr)and


    notexists(selectmitarbeiternr,jahr,urlaubsanspruchfrom[dbo].TB_Urlaubsanspruch_Testu5whereu5.mitarbeiternr=u1.mitarbeiternrandu5.jahr=@jahr);

    set@jahr=@jahr+1

    end

    Go



    Viele Grüße
    Lara
    • Bearbeitet Lara V Freitag, 9. Februar 2018 09:45
    Freitag, 9. Februar 2018 09:44