MainframeSupports
tip uge 28/2008:

En af mine yndlingsemner i ugens tip er brugen af subselect i SQL-kald. Med DB2 version 8 er der dukket endnu flere muligheder op. Faktisk er det i DB2 version 8 i new function mode tilladt at benytte en subselect alle de steder, hvor det er tilladt at benytte en expression. Det betyder blandt andet, at det er tilladt at skrive subselects i sin select-liste:

SELECT (SELECT MIN(CREATOR) FROM SYSIBM.SYSTABLES)
FROM SYSIBM.SYSDUMMY1

Dette er et fuldt lovligt SQL-kald i DB2 version 8. Jeg er sikker på, at du kan udtænke mange kreative måder at benytte denne nye mulighed på. Men som sædvanlig vokser træerne ikke helt ind i himlen. En subselect som expression tillader ikke, at tabelnavnet indeholder en location.

Som overskriften til dette tip antyder, har jeg fundet min egen kreative måde at benytte en subselect som expression. Jeg har en tabel med historik, hvor jeg tilfældigvis ved, at der kun er een række for hver forekomst (kunde, konto, police, ordre eller hvad tabellen nu indeholder historik om), når en given kolonne indeholder en bestemt værdi. I sådanne tilfælde kan jeg optimere min subselect til fremfinding af den gældende version (se i øvrigt uge 26/2003), men kun hvis SQL-kaldet skal behandle flere forekomster. Ved behandling af een forekomst er det bedst tænkelige SQL-kald behandlet i uge 40/2007. Først et SQL-kald før optimering:

SELECT keycolumn1, columna, columnb
FROM tablex x
WHERE columnd = 4
  AND keycolumn2 =
( SELECT MAX(keycolumn2)
  FROM tablex
  WHERE keycolumn1 = x.keycolumn1
)

Jeg ved tilfældigvis, at columnc indeholder værdien 'NOHIST', hvis der kun er een række i tabellen for den pågældende forekomst identificeret ved keycolumn1. Denne viden kan jeg benytte til en lettere omskrivning af ovenstående SQL-kald:

SELECT keycolumn1, columna, columnb
FROM tablex x
WHERE columnd = 4
  AND keycolumn2 =
CASE columnc WHEN 'NOHIST' THEN keycolumn2 ELSE
( SELECT MAX(keycolumn2)
  FROM tablex
  WHERE keycolumn1 = x.keycolumn1
) END

Ved hjælp af CASE får jeg enten returneret værdien af keycolumn2 direkte eller den højeste værdi af keycolumn2 fra subselect'en. Subselect'en udføres kun, hvis columnc indeholder en anden værdi end 'NOHIST'. Hvis en stor andel af forekomsterne i tablex har værdien 'NOHIST' i columnc, så vil det optimerede SQL-kald køre langt hurtigere end før optimeringen. Det afhænger altså i høj grad af opbygningen af data om optimeringen kan betale sig.

Forrige danske tip        Last tip in english        Tip oversigten