LesezeichenAbonnierenRSS-Feed abonnieren
FK55
Fluorite | Level 6

Hallo,

 

ich bin noch relativ unerfahren im Umgang mit SAS und verwende SAS EG 6.1. Ich habe eine Datenbank mit Verträgen. Leider gibt es für jeden aktiven Vertrag für jeden Monatsstand (Format TT/MM/YYYY) einen eigenen Datensatz; wird ein Vertrag gekündigt, so taucht er ab Kündigungsmonat nicht mehr auf. Ich möchte diese Datenbank filtern, so dass ich jeden Vertrag mit dem jeweils jüngsten Monatsstand erhalte (also dem letzten Monat, in dem der Vertrag aktiv war).

 

In der Excel-Datei habe ich ein Beispiel dargestellt: Die Daten sind bereits nach Verträgen und Datenständen sortiert; Ziel ist, nur die jeweils gelb markierten Datensätze (jüngstes Datum) zu erhalten.

 

Vielen Dank für die Hilfe

 

F. Kraus

 

 

6 ANTWORTEN 6
jh_ti_bw
Obsidian | Level 7

Hallo FK55,

Du kannst nach dem größten Wert suchen, wenn das Datum nicht als Text sondern als Datum definiert ist:

Data test;
  informat DAT_STND anydtdte.;
  Format   DAT_STND DDMMYYP10.;
  informat VNR $8.;
  input DAT_STND VNR;
  cards; 
1/31/2012 44010269 
2/29/2012 44010269 
3/31/2012 44010269 
4/30/2012 44010269 
5/31/2012 44010269 
6/30/2012 44010269 
7/31/2012 44010269 
8/31/2012 44010269 
9/30/2012 44010269 
1/31/2012 44015907 
2/29/2012 44015907 
3/31/2012 44015907 
4/30/2012 44015907 
5/31/2012 44015907
run;
Proc sql;
  Create table kuend as 
  select * 
  from test
  group by vnr
  having DAT_STND = Max(DAT_STND)
  ;
quit; 

VG

Jan

Dennis_V
Calcite | Level 5

Bei dem SQL kann man auch die HAVING-Klausel weglassen:

 

PROC SQL;

  CREATE TABLE NEUSTE_VERTRAEGE AS

  SELECT VTR

        ,MAX(DTM) AS DTM FORMAT=DDMMYYP10.

  FROM VERTRAEGE

  GROUP BY VTR;

QUIT;

 

Dann wird auch die folgende NOTE vermieden:

 

NOTE: The query requires remerging summary statistics back with the original data.

Dennis_V
Calcite | Level 5

Hallo FK55,

 

ich habe die Einlesedaten stark vereinfacht, aber es ist das selbe Prinzip:

 

DATA VERTRAEGE;

  ATTRIB VTR FORMAT=4.;

  ATTRIB DTM FORMAT=DDMMYYP10. INFORMAT=DDMMYY10.;

  INPUT VTR DTM;

DATALINES;

2345 01.01.2015

3456 01.01.2015

2345 01.01.2017

2345 01.01.2016

3456 01.01.2016

1234 01.01.2017

;

RUN;

 

PROC SORT DATA=VERTRAEGE;

  BY VTR DESCENDING DTM;

RUN;

 

DATA NEUSTE_VERTRAEGE;

  SET VERTRAEGE;

  BY VTR DESCENDING DTM;

  IF FIRST.VTR;

RUN;

 

Viele Grüße

 

Dennis

FK55
Fluorite | Level 6

erst einmal herzlichen Dank für die schnellen Antworten - ich habe nun versucht, die Selektion in eine Abfrage einzubauen, leider erfolglos. Auch der Weg über einen Stored Process führte nur zu Fehlermeldungen (DAT_STD ist als Datum formatiert):

 

71 PROC SQL;

72 CREATE TABLE WORK.SORTIERT_VERT_STAND AS

73 SELECT t1.DAT_STND,

74 t1.VNR,

75 t1.PZ_VNR,

76 t1.'AG GEB'n,

Das SAS System

77 t1.AG_BEZ,

78 t1.BSSEU,

79 t1.SALDOIST,

80 t1.RSB,

81 t1.ABDAT,

82 t1.KUENDDAT,

83 t1.ZUTDAT,

84 t1.ZUST,

85 t1.Zustand,

86 t1.TARIF,

87 t1.PRODNR,

88 t1.'Bezeichnung kurz'n,

89 t1.PZSTRUK,

90 t1.PZVERTR,

91 t1.abstruk,

92 t1.ABVERTR,

93 t1.GEBDAT,

94 t1.BERUF,

95 t1.FAMSTD,

96 t1.IHNR,

97 t1.VNR1

98 FROM WORK.FILTER_FOR_BEST_BS_HIST_0001 t1

99 ORDER BY t1.VNR,

100 t1.DAT_STND DESC;

       

Spoiler
die Zeilen bis hierher werden vom System erzeugt, dennoch kommt die Meldung, dass die Datei nicht exisitiert

 

ERROR: Datei WORK.FILTER_FOR_BEST_BS_HIST_0001.DATA existiert nicht.

NOTE: PROC SQL set option NOEXEC and will continue to check the syntax of statements.

        

Spoiler
nach der Sortierung wollte ich eigentlich die Selektion vornehmen, aber auch hier erhalte ich nur eine Fehlermeldung

 

101

102 CREATE TABLE NEUSTE_VERTRAEGE AS

103 SELECT t1.VNR

104 ,MAX(t1.DAT_STND) AS t1.DAT_STND FORMAT=DDMMYYP10.

_

22

76

ERROR 22-322: Syntax error, expecting one of the following: eine Zeichenkette in Hochkommata, ',', AS, FORMAT, FROM, INFORMAT, INTO, LABEL, LEN, LENGTH, TRANSCODE.

ERROR 76-322: Syntax error, statement will be ignored.

105 FROM WORK.FILTER_FOR_BEST_BS_HIST_0001 t1

Das SAS System

106 GROUP BY t1.VNR;

107

108 QUIT;

NOTE: The SAS System stopped processing this step because of errors.

NOTE: PROZEDUR SQL used (Total process time):

real time 0.02 seconds

cpu time 0.00 seconds

 

109 /* --- Ende des Codes für "Filtern und sortieren1". --- */

 

 

Viele Grüße

Florian

Dennis_V
Calcite | Level 5

Beim zweiten SQL schreibst du:

 

,MAX(t1.DAT_STND) AS t1.DAT_STND

 

nach dem AS musst du das t1. entfernen:

 

,MAX(t1.DAT_STND) AS DAT_STND

 

 

Der erste SQL sieht soweit richtig aus. Da liegt das wahrscheinlich an der Prozedur davor.

jh_ti_bw
Obsidian | Level 7

Hallo Florian,

 

zusätzlich greifst Du auf eine Datei zu, die nicht existiert.

 

ERROR: Datei WORK.FILTER_FOR_BEST_BS_HIST_0001.DATA existiert nicht.

@Dennis: Dein Einwand, dass das having zu einer Note führt ist richtig. Der Code führt auch in beiden Fällen bei der verwendeten Tabelle zu dem gleichen Ergebnis. Möchte man aber weitere Attribute einer Tabelle haben wird das Ergebnis unterschiedlich sein und es wird die gleiche Note ausgegeben.

Die Note besagt auch nur, dass SAS eine Erweiterung zum SQL-Standard nutzt, dich ich sehr praktisch finde.

Wenn man die Note vermeiden wollte wäre ein adäquater Code z. B:

Proc sql;
  Create table kuend as 
  select T1.* 
  from FILTER_FOR_BEST_BS_HIST_0001 as T1
  , (
    select VNR
    , Max(DAT_STND) as DAT_STND 
    from FILTER_FOR_BEST_BS_HIST_0001 
    group by VNR
    ) as T2
  where T1.VNR      = T2.VNR 
    and T1.DAT_STND = T2.DAT_STND
  ;
quit; 

Man müsste das remerging, dass SAS im ersten Fall selbständig ausführt, explizit programmieren.

 

Viele Grüße

Jan

 

 

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

Diskussionsstatistiken
  • 6 Antworten
  • 3555 Aufrufe
  • 0 Kudos
  • 3 in Unterhaltung