28. november 2003 - 11:37Der er
24 kommentarer og 2 løsninger
Vis indhold på trods af manglende forekomst
Jeg har en sql-sætning. Følgende er en stump heraf, som ikke melder syntaxfejl, men som stadigvæk har fejl.
SELECT medarb.nr, medarb.navn, gruppe1.timer FROM (SELECT DISTINCT sagspost.nr, medarbejder.medarbejder_navn AS navn FROM sagspost, medarbejder WHERE sagspost.posteringsdato BETWEEN '2000.01.01' AND '2003.10.31' AND sagspost.nr = medarbejder.nr) medarb INNER JOIN (SELECT sagspost.nr, SUM sagspost.antalregistreret) timer FROM sagspost WHERE sagspost.posteringsdato BETWEEN '2000.01.01' AND '2003.10.31' AND (sagspost.aktivitetsnummer BETWEEN '080' AND '189') GROUP BY sagspost.nr) gruppe1 ON medarb.nr = gruppe1.nr
Hvis sætningen er for kompliceret, så er det heller ikke sikkert, at den er nødvendig at kende, for at løse mit problem. Problemet er:
Hvis en medarbejder ikke har en time-forekomst indenfor aktivitetsgruppe 080 og 189 som anført i sql'en ovenfor, så bliver denne medarbejder helt udelukket fra visningen. Det skal han/hun ikke. Derudover, når jeg senere kobler flere aktivitetsgrupper på, så forsvinder der endnu flere medarbejdere, hvis ikke de har et aktivitetsnummer i alle intervallerne. Så til sidst, når jeg har alle 5 grupper af aktivitetsnumre slået til, så er ikke en eneste medarbejder vist, da der ikke er en eneste af dem, der har timer indenfor alle områderne. Jeg vil gerne have, at alle medarbejdere bliver vist OGSÅ selvom de ikke har timer i et interval. Så skal der bare stå "0".
Jeg har hentet data fra en Oracle-database, og der kan jeg benytte syntaxen "(+)" for at inkludere grupper, også selvom de er tomme. Hvad er den tilsvarende syntax i SQL-server?
Denne side indeholder artikler med forskellige perspektiver på Identity & Access Management i private og offentlige organisationer. Artiklerne behandler aktuelle IAM-emner og leveres af producenter, rådgivere og implementeringspartnere.
Du skal benytte enten en LEFT OUTER JOIN eller en RIGHT OUTER JOIN i ovenstående tilfælde. I ekstreme tilfælde kan du være nød til at lave en FULL OUTER JOIN.
Bemærk i øvrigt, at når du laver OUTER JOINS bliver brug af indeks ekstremt dårlig - ofte vil du ende med rene tablescans, hvilket er langsomt.
I øvrigt: Er du i en situation hvor du ender med multiciple OUTER JOINS i samme statement er det typisk et tegn på, at du ikke har fået gennemtænkt dit udtræk. I de tilfælde hvor det er nødvendigt, kan det ofte betale sig at vurdere effekten af en FULL OUTER JOIN eller en CROSS JOIN kombineret med en eller flere begrænsende INNER JOINS.
Det er i øvrigt mere korrekt og læsevenligt at bruge den fulde syntaks fremfor blot JOIN og LEFT JOIN / RIGHT JOIN.
Jeg kan ikke finde ud af, at passe en LEFT OUTER JOIN ind i sql-sætningen. Jeg får en fejl, hvis jeg skriver:
sql="SELECT medarb.nr, medarb.navn, gruppe1.timer FROM "+ "(SELECT DISTINCT sagspost.nr, medarbejder.medarbejder_navn FROM "+ "sagspost, medarbejder WHERE "+ "sagspost.posteringsdato BETWEEN '01-01-2000' AND '12-31-2003' "+ "AND "+ "sagspost.nr = medarbejder.nr) medarb LEFT JOIN "+ "(SELECT sagspost.nr, SUM sagspost.antalregistreret) timer FROM sagspost WHERE "+ "sagspost.posteringsdato BETWEEN '01-01-2000' AND '12-31-2003' "+ "AND "+ "(sagspost.aktivitetsnummer BETWEEN 80 AND 189) "+ "GROUP BY sagspost.nr) gruppe1 ON medarb.nr = gruppe1.nr";
Ja, det er rigtigt. Jeg så godt den med parantesen efter SUM. Jeg ved ikke helt hvad du mener med Stored Procedure... jeg redigerer jo SQL-sætningen dynamisk alt efter brugerens indtastning.
create procedure spSomething ( @startdato datetime, @slutdato datetime, @aktstart int, @aktslut int ) as SELECT medarb.nr, medarb.navn, gruppe1.timer FROM (SELECT DISTINCT sagspost.nr, medarbejder.medarbejder_navn FROM "+ sagspost inner join medarbejder on sagspost.nr = medarbejder.nr WHERE sagspost.posteringsdato BETWEEN @startdato AND @slutdato ) medarb LEFT outer JOIN (SELECT sagspost.nr, SUM sagspost.antalregistreret timer FROM sagspost WHERE sagspost.posteringsdato BETWEEN @startdato AND @slutdato AND (sagspost.aktivitetsnummer BETWEEN @aktstart AND @aktslut) GROUP BY sagspost.nr) gruppe1 ON medarb.nr = gruppe1.nr go
Det betyder såmænd ikke noget. Det hele kører automatisk på serveren. Brugeren får jo kun det at se, som queryen returnerer. Det er i hvert tilfælde ikke så vigtigt lige nu. Det helt essentielle er, at jeg kan trække al data ud - også når der ikke står noget under en medarbejder. Så skal der bare stå "0".
Så tak for eksemplet, men har du ikke mulighed for i stedet at vise mig hvordan jeg får alle medarbejdere med? Jeg har lavet en LEFT OUTER JOIN nu, og den virker fint. Nu skal jeg bare lige have testet den med 2 grupper.
Nu virker det hele. Og det var bare at skrive LEFT OUTER JOIN i en stor pærevælling... ahhh. nu bliver det en god weekend.
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.