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:
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:
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:
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.