none
SQL Statment für letzten Datensatz einer Gruppe gesucht RRS feed

  • Frage

  • Hallo an alle,

    ich habe eine Tabelle in der für jeden Kunden mehrfach Daten gespeichert sind und ich suche nun ein SQL-Statment, bei dem ich den jeweils letzten Datensatz je Kunde bekomme:

    ID  KdnNr  Kunde        Datum                Ergebnis

    1    1         Kunde 1      10.08.2010              50

    2    1         Kunde 1      20.09.2010              57

    3    2         Kunde 2     13.08.2010               43

    4    1         Kunde 1     05.10.2010                23

     

    Als Ergebnis hätte ich gern:

    3    2         Kunde 2     13.08.2010               43

    4    1         Kunde 1     05.10.2010                23

     

    Irgendwie stehe ich immer wieder vor diesem Problem. Gibt es da was elegantes? Wie ist das mit "Partition over"?

    Oder geht nur der Ansatz

    Select a.Kdnnr, a.Kunde, a.Datum, a.Ergebnis from Kundentabelle a where a.Datum = 
    (select max(b.Datum) from Kundentabelle b where a.Kdnnr = b.Kdnnr)order by Kdnnr, Datum

    Und was wäre, wenn an einem Tag zwei Einträge existieren würden?

     

    Vielen Dank schon mal

    und schönen Abend

    Karline

     


    Samstag, 6. November 2010 22:55

Antworten

  • Hallo Karline,

    Version 1

    declare @t1 table
    (
    	id int identity(1,1),
    	KdnNr int,
    	Kunde varchar(255),
    	Datum datetime,
    	Ergebnis int
    )
    
    insert into @t1
    values
    (1,'Kunde 1','2010-08-10',50),
    (1,'Kunde 1','2010-09-20',57),
    (2,'Kunde 2','2010-08-13',43),
    (1,'Kunde 1','2010-10-05',23)
    
    ;with t1 as
    (
    	select
    		KdnNr,
    		max(Datum) as Datum
    	from @t1
    	group by KdnNr
    )
    select t2.id,t2.KdnNr,t2.Kunde,t2.Datum,t2.Ergebnis 
    from
    	t1 inner join @t1 t2
    	on t1.KdnNr=t2.KdnNr
    	and t1.Datum=t2.Datum
    order by t2.id
    

    Gruß Yury
    Samstag, 6. November 2010 23:23
  • Hallo Karline,

    Version 2

    declare @t1 table
    (
    	id int identity(1,1),
    	KdnNr int,
    	Kunde varchar(255),
    	Datum datetime,
    	Ergebnis int
    )
    
    insert into @t1
    values
    (1,'Kunde 1','2010-08-10',50),
    (1,'Kunde 1','2010-09-20',57),
    (2,'Kunde 2','2010-08-13',43),
    (1,'Kunde 1','2010-10-05',23)
    
    ;with t1 as(
    select
    	row_number() over(partition by KdnNr order by Datum desc) as rn,
    	id,
    	KdnNr,
    	Kunde,
    	Datum,
    	Ergebnis
    from @t1
    )
    select
    	id,
    	KdnNr,
    	Kunde,
    	Datum,
    	Ergebnis
    from
    	t1
    where
    	rn < 2
    order by
    	id
    

    Gruß Yury
    Samstag, 6. November 2010 23:42
  • Und was wäre, wenn an einem Tag zwei Einträge existieren würden?


    Hallo Karline,

    hier solltest Du selbst entscheiden, ob die Daten aggregiert oder nur der zuletzt gespeicherte Datensatz zurück geliefert wird z.B.:

    Version 3

    declare @t1 table
    (
    	id int identity(1,1),
    	KdnNr int,
    	Kunde varchar(255),
    	Datum datetime,
    	Ergebnis int
    )
    
    insert into @t1
    values
    (1,'Kunde 1','2010-08-10',50),
    (1,'Kunde 1','2010-09-20',57),
    (2,'Kunde 2','2010-08-13',43),
    (1,'Kunde 1','2010-10-05',23),
    (1,'Kunde 1','2010-10-05',24)
    
    
    ;with t1 as(
    select
    	row_number() over(partition by KdnNr order by Datum desc, id desc ) as rn,
    	id,
    	KdnNr,
    	Kunde,
    	Datum,
    	Ergebnis
    from @t1
    )
    select
    	id,
    	KdnNr,
    	Kunde,
    	Datum,
    	Ergebnis
    from
    	t1
    where
    	rn < 2
    order by
    	id
    

    Gruß Yury
    Samstag, 6. November 2010 23:56

Alle Antworten

  • Hallo Karline,

    Version 1

    declare @t1 table
    (
    	id int identity(1,1),
    	KdnNr int,
    	Kunde varchar(255),
    	Datum datetime,
    	Ergebnis int
    )
    
    insert into @t1
    values
    (1,'Kunde 1','2010-08-10',50),
    (1,'Kunde 1','2010-09-20',57),
    (2,'Kunde 2','2010-08-13',43),
    (1,'Kunde 1','2010-10-05',23)
    
    ;with t1 as
    (
    	select
    		KdnNr,
    		max(Datum) as Datum
    	from @t1
    	group by KdnNr
    )
    select t2.id,t2.KdnNr,t2.Kunde,t2.Datum,t2.Ergebnis 
    from
    	t1 inner join @t1 t2
    	on t1.KdnNr=t2.KdnNr
    	and t1.Datum=t2.Datum
    order by t2.id
    

    Gruß Yury
    Samstag, 6. November 2010 23:23
  • Hallo Karline,

    Version 2

    declare @t1 table
    (
    	id int identity(1,1),
    	KdnNr int,
    	Kunde varchar(255),
    	Datum datetime,
    	Ergebnis int
    )
    
    insert into @t1
    values
    (1,'Kunde 1','2010-08-10',50),
    (1,'Kunde 1','2010-09-20',57),
    (2,'Kunde 2','2010-08-13',43),
    (1,'Kunde 1','2010-10-05',23)
    
    ;with t1 as(
    select
    	row_number() over(partition by KdnNr order by Datum desc) as rn,
    	id,
    	KdnNr,
    	Kunde,
    	Datum,
    	Ergebnis
    from @t1
    )
    select
    	id,
    	KdnNr,
    	Kunde,
    	Datum,
    	Ergebnis
    from
    	t1
    where
    	rn < 2
    order by
    	id
    

    Gruß Yury
    Samstag, 6. November 2010 23:42
  • Und was wäre, wenn an einem Tag zwei Einträge existieren würden?


    Hallo Karline,

    hier solltest Du selbst entscheiden, ob die Daten aggregiert oder nur der zuletzt gespeicherte Datensatz zurück geliefert wird z.B.:

    Version 3

    declare @t1 table
    (
    	id int identity(1,1),
    	KdnNr int,
    	Kunde varchar(255),
    	Datum datetime,
    	Ergebnis int
    )
    
    insert into @t1
    values
    (1,'Kunde 1','2010-08-10',50),
    (1,'Kunde 1','2010-09-20',57),
    (2,'Kunde 2','2010-08-13',43),
    (1,'Kunde 1','2010-10-05',23),
    (1,'Kunde 1','2010-10-05',24)
    
    
    ;with t1 as(
    select
    	row_number() over(partition by KdnNr order by Datum desc, id desc ) as rn,
    	id,
    	KdnNr,
    	Kunde,
    	Datum,
    	Ergebnis
    from @t1
    )
    select
    	id,
    	KdnNr,
    	Kunde,
    	Datum,
    	Ergebnis
    from
    	t1
    where
    	rn < 2
    order by
    	id
    

    Gruß Yury
    Samstag, 6. November 2010 23:56
  • Hallo Yury,

     

    Danke für die sehr ausführliche Antwort!

    Und diesen "with t1 as" Konstrukt kannte ich so auch nicht, ist aber total hilfreich.

    Besten Dank nochmal!!!

    Montag, 8. November 2010 14:49