MainframeSupports
tip uge 45/2014:

Jeg håber, du kender og forstår, hvordan GROUP BY i SQL virker, ellers bliver det nok en smule svært at forstå ideen i denne uges tip. Forestil dig, at du ønsker at udføre noget GROUP BY lignende funktionalitet på et dataset eller member. Du kan selvfølgelig vælge at oprette en DB2 tabel og loade datasettet ind i tabellen, men det er sandsynligvis langt hurtigere at bruge DFSORT til formålet.

I det følgende eksempel har jeg et RECFM=FB og LRECL=80 dataset (meget udbredt). I de første 40 tegn har jeg de data, der skal laves GROUP BY på. Jeg vil i øvrigt gerne vide, hvor mange records, der er i hver "gruppe". De sidste 40 tegn i filen er ligegyldige lige i denne sammenhæng. Opgaven kan løses med følgende step:

//GROUPBY  EXEC PGM=SORT
//SORTIN   DD DISP=SHR,DSN=MY.ORDINARY.DATASET
//SORTOUT  DD DISP=(NEW,CATLG),SPACE=(TRK,(99,99),RLSE),
//         DSN=MY.GROUP.BY
//SYSOUT   DD SYSOUT=*
//SYSIN    DD *
    INREC FIELDS=(1,40,C' 000000001',30X)
    SORT FIELDS=(1,40,CH,A)
    SUM FIELDS=(42,9,ZD)
/*

Ved hjælp af INREC opbygger jeg udseendet af de data, der skal laves sort og sum på. Da hver record kun skal tælle som 1 til den samlede sum for hver gruppe, sætter jeg nøglen sammen med en læsbar værdi på 1, og for at skille gruppen fra summen/antallet har jeg indsat en blank. DFSORT er lidt touchy mht. bevarelse af længden, så jeg sætter lige 30 blanke på for stadig at have en LRECL på 80. Selve SORT funktionen udføres på udseendet af record'en efter den har været en tur gennem INREC. Her sorterer jeg så på de tegn, der udgør gruppen. Her kan jeg let lave om på gruppen ved at sortere på dele af de 40 tegn, hvis det er interessant. SUM funktionen summerer alle et-tallerne i pos.42-50 i hver gruppe.

Resultatet er tilgængeligt i MY.GROUP.BY datasettet. Som du måske ved, så kører SORT utroligt stærkt, så det tager ikke mange sekunder at producere resultatet, selv på store datamængder. Og det er let lige at ændre på SORT parameteren, hvis der ønskes en anden gruppering. Det er selvfølgelig ikke lige så let læseligt som et SQL SELECT statement med GROUP BY, men det er langt hurtigere end først at oprette en tabel og loade data.

Du kan selvfølgelig summere på felter i datasettet, der allerede er numeriske, men du behøver faktisk slet ikke at have nogle numeriske felter at lave SUM på. Det kan jo tænkes, at du kun er interesseret i selve gruppen, og ligeglad med, hvor mange records, der er i den. Så skal du bare benytte en SUM FIELDS=NONE, og så behøver du ikke heller ikke lave en INREC for at have et felt at summere på.

Forrige danske tip        Last tip in english        Tip oversigten