16. juli 2004 - 13:09Der er
13 kommentarer og 2 løsninger
SQL forespørgsel
Hej
Jeg har en tabel indeholdene følgende felter:
IPadresse IDstatus
IDstatus kan indeholde flere forskellige værdier, normal vil den indeholde i seks cifret tal, men hvis den ikke har læst et nummer vil der stå NOREAD. Hvordan kan man lave en forspørgsel som giver følgede resultat
Jeg er ikke sikker på jeg helt forstår opgaven, men måske sådan her:
select a.IPAdresse, AntalLaest, AntalIkkeLaest from ( select IPAdreesse, count(*) as AntalIkkeLaest from MyTable where IDStatus='NOREAD' group by IPAdresse ) a, ( select IPAdreesse, count(*) as AntalIkkeLaest from MyTable where IDStatus!='NOREAD' group by IPAdresse ) b where a.IPAdresse=b.IPAdresse;
Du kan udnytte at count(<noget>) kun tæller ikke-null værdier :
select ipadresse, count(case when idstatus = 'NOREAD' then null else 1 end) antallaest, count(case when idstatus = 'NOREAD' then 1 else null end) antalikkelaest from tabel group by ipadresse
select ipadresse, count(case when isnumeric(idstatus) then 1 else null end) antallaest, count(case when isnumeric(idstatus) then null else 1 end) antalikkelaest from tabel group by ipadresse
På den måde slipper man også for afhængigheden af det "hard-codede" NOREAD.
select ipadresse, antallaest, antalikkelaest, case when antallaest+antalikkelaest > 0 then 100*antallaest/(antallaest+antalikkelaest) else 0 end pctlaest, case when antallaest+antalikkelaest > 0 then 100*antalikkelaest/(antallaest+antalikkelaest) else 0 end pctikkelaest from ( select ipadresse, count(case when isnumeric(idstatus) then 1 else null end) antallaest, count(case when isnumeric(idstatus) then null else 1 end) antalikkelaest from tabel group by ipadresse ) s
select ipadresse, antallaest, antalikkelaest, 100*antallaest/(antallaest+antalikkelaest) pctlaest, 100*antalikkelaest/(antallaest+antalikkelaest) pctikkelaest from ( select ipadresse, count(case when isnumeric(idstatus) then 1 else null end) antallaest, count(case when isnumeric(idstatus) then null else 1 end) antalikkelaest from tabel group by ipadresse ) s
Årsagen til du kan nøjes med det er, at antallaest og antalikkelaest er komplementære, så du kan være sikker på, at antallaest+antalikkelaest vil altid være > 0.
Men generelt bør man huske tjekket for ikke at få "division med nul" fejl...
select ipadresse, antallaest, antalikkelaest, 100*antallaest/(antallaest+antalikkelaest) pctlaest, 100*antalikkelaest/(antallaest+antalikkelaest) pctikkelaest from ( select ipadresse, count(nullif(isnumeric(idstatus),1)) antallaest, count(nullif(isnumeric(idstatus),0)) antalikkelaest from tabel group by ipadresse ) s
Jeg havde lige glemt nullif(), som netop er en specialiseret case til dette formål...
Syntax fejlen er nok min fejl. Dette skulle virke :
select ipadresse, antallaest, antalikkelaest, 100*antallaest/(antallaest+antalikkelaest) pctlaest, 100*antalikkelaest/(antallaest+antalikkelaest) pctikkelaest from ( select ipadresse, count(case when isnumeric(idstatus)=1 then 1 else null end) antallaest, count(case when isnumeric(idstatus)=1 then null else 1 end) antalikkelaest from tabel group by ipadresse ) s
Men endnu bedre er nullif() konstruktionen i foregående kommentar.
Men jeg må nok virkelig fraråde alle de besynderlige statements med cases og subselects osv. De performer virkelig dårligt når der er mange rækker i tabellen.
Og hvad angår performance kan jeg da sige jeg benytter både case og subselects og mange andre konstruktioner i store sql-statements med mange joins og på tabeller med mange rækker i vores 300GB Oracle database - og det performer *rigtig* godt...
Det er muligt det ikke performer helt så godt i MS SQL - den har jeg knap så stor erfaring med. Jeg har mest brugt MS SQL til mindre baser. Så hvis du siger det ikke performer i MS SQL, så skal jeg ikke modsige dig (alt for meget i hvert fald :-)
Så der kan jeg kun anbefale kxh at afprøve tingene og se hvorvidt de performer...
Der er en lille detalje, som nogen brugere måske vil hænge sig i, kan man få procenten vis med decimaler, da den f.eks lige nu skrive 91 og 8 hvor er den sidste, vil de sikkert spørge ??
// Kim
Synes godt om
Ny brugerNybegynder
Din løsning...
Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.