
Ved Renden 31 2870 Dyssegaard Tel. +45 23 34 54 43
| 
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
|