Avatar billede el_fredo Praktikant
16. oktober 2003 - 16:39 Der er 15 kommentarer og
1 løsning

SQL hjælp søges

Jeg har, som en del af min SQL-sætning, følgende stump:

(SELECT sagspost.medarbejdernummer nr, sum sagspost.antalregistreret) timer FROM test.sagspost WHERE sagspost.posteringsdato BETWEEN '2002.01.01' AND '2003.10.31' AND (sagspost.aktivitetsnummer = '908') GROUP BY sagspost.medarbejdernummer) gruppe5

Den virker (syntaxmæssigt) fint, og er som nævnt taget ud af en kontekst, så I behøver ikke nævne, at der er fejl i sætningen. Problemet er imidlertid, at jeg i linien hvor der står "sagspost.aktivitetsnummer = '908'" får null ud af HELE mit SQL kald, hvis der ikke er et eneste sted i databasen hvor aktivitetsnummeret er 908. Da 908 henfører til ferie, er der tit (i starten af kalenderåret) hvor der ikke er anført ferie, og jeg kan derfor ikke få de andre informationer ud (hvilket jeg skal). Hvordan kan jeg snørkle den, så jeg får de andre informationer ud, også selvom der ikke er nogle forekomster af "908"? Det SKAL være i samme SQL-kald, da jeg autogenererer en XML-fil, og det vil være for omstændigt at skulle lave kode der kan sætte 2 XML-dokumenter sammen.

Jeg benytter i øvrigt C#.
Avatar billede Slettet bruger
16. oktober 2003 - 19:56 #1
Øh hvorfor fjerner du ikke bare den del af where som siger at aktivitetsnr skal være 908? Det er jo korrekt at du ikke får noget ud når du siger at den skal være 908 eller har jeg misforstået noget?
Avatar billede el_fredo Praktikant
16. oktober 2003 - 22:54 #2
Ja, men nogle gange kan der jo godt være noget med 908 listet. Hvis jeg fjerner den, så får jeg jo aldrig oplysninger om ferie...
Avatar billede arne_v Ekspert
17. oktober 2003 - 09:38 #3
Jeg har svært ved at gennemskue problem-stillingen helt.

Min umiddelbare fornemmelse er at hvis du i den rigtige kontekst:
* laver LEFT JOIN på sagspost
* (tester sagspost.aktivitetsnummer = '908' OR sagspost.aktivitetsnummer IS NULL)
så vil du få det du ønsker.
Avatar billede el_fredo Praktikant
17. oktober 2003 - 10:32 #4
Det jeg skal, er at samle nogle timetal fra en tabel (sagspost) og alt efter deres aktivitetsnummer, skal de vises i deres respektive kolonner. 908 er som sagt ferie, men det kan jo godt være, at fx internt arbejde (fx kode 208) heller ikke er anført. Kommer man så ikke til at medtage dem også? Det betyder måske ikke så meget, når de er null??? Vil du have hele SQL-sætningen?
Avatar billede el_fredo Praktikant
17. oktober 2003 - 10:33 #5
Jeg har ikke helt styr på LEFT JOIN, INNER JOIN osv. men det er jo en anden sag ;o)
Avatar billede el_fredo Praktikant
17. oktober 2003 - 10:36 #6
Nå, her kommer SQL-sætningen:

sql="SELECT medarb.fag Fag,medarb.nr Nr,medarb.navn Navn, gruppe1.timer Gruppe_1,gruppe2.timer,gruppe4.timer,gruppe6.timer,gruppe7.timer FROM (SELECT DISTINCT medarbejder.faggruppe fag,sagspost.medarbejdernummer  nr,medarbejder.navn1 navn FROM test.sagspost, test.medarbejder WHERE sagspost.posteringsdato BETWEEN '2002.01.01' AND '2002.10.31' AND sagspost.medarbejdernummer = medarbejder.medarbejdernummer) medarb, (SELECT sagspost.medarbejdernummer nr, sum(sagspost.antalregistreret) timer FROM test.sagspost WHERE sagspost.posteringsdato BETWEEN '2002.01.01' AND '2002.07.31' AND (sagspost.aktivitetsnummer BETWEEN '080' AND '189') GROUP BY sagspost.medarbejdernummer) gruppe1, (SELECT sagspost.medarbejdernummer nr, sum(sagspost.antalregistreret) timer FROM test.sagspost WHERE sagspost.posteringsdato BETWEEN '2002.01.01' AND '2002.07.31' AND (sagspost.aktivitetsnummer BETWEEN '190' AND '199') GROUP BY sagspost.medarbejdernummer) gruppe2, (SELECT sagspost.medarbejdernummer nr,sum(sagspost.antalregistreret) timer FROM test.sagspost WHERE sagspost.posteringsdato BETWEEN '2002.01.01' AND '2002.07.31' AND (sagspost.aktivitetsnummer BETWEEN '901' AND '906' OR sagspost.aktivitetsnummer BETWEEN '910' AND '939') GROUP BY sagspost.medarbejdernummer) gruppe4, (SELECT sagspost.medarbejdernummer nr,sum(sagspost.antalregistreret) timer FROM test.sagspost WHERE sagspost.posteringsdato BETWEEN '2002.01.01' AND '2003.10.31' AND (sagspost.aktivitetsnummer = '908') GROUP BY sagspost.medarbejdernummer) gruppe5,(SELECT sagspost.medarbejdernummer nr, sum(sagspost.antalregistreret) timer FROM test.sagspost WHERE sagspost.posteringsdato BETWEEN '2002.01.01' AND '2002.07.31' AND (sagspost.aktivitetsnummer = '907') GROUP BY sagspost.medarbejdernummer) gruppe6, (SELECT sagspost.medarbejdernummer nr, sum(sagspost.antalregistreret) timer FROM test.sagspost WHERE sagspost.posteringsdato BETWEEN '2002.01.01' AND '2002.07.31' AND (sagspost.aktivitetsnummer = '909') GROUP BY sagspost.medarbejdernummer) gruppe7 WHERE medarb.nr = gruppe1.nr(+) AND medarb.nr = gruppe2.nr(+) AND medarb.nr = gruppe4.nr(+) AND medarb.nr = gruppe6.nr(+) AND medarb.nr = gruppe7.nr(+) ORDER BY medarb.fag, medarb.nr";

Det var så den...
Avatar billede el_fredo Praktikant
17. oktober 2003 - 10:38 #7
Og problemet med ferie er jo ikke kun der. Problemet ville vel opstå, så snart der var et felt, hvor der ingen resultater var at finde nogen steder. Så sikringen med "OR = null" skal vel med alle stederne.
Avatar billede Slettet bruger
17. oktober 2003 - 16:39 #8
Hvilken database benytter du?
Hvis det er sql server kan du gøre sådan for at få null med:
IsNull(sagspost.aktivitetsnummer,'908') = '908'
Avatar billede el_fredo Praktikant
22. oktober 2003 - 09:36 #9
Jeg bruger Oracle i dette tilfælde, men det skal helst laves sådan, at SQL-sætningen kan bruges på flere DBMS'er.
Avatar billede el_fredo Praktikant
05. november 2003 - 08:51 #10
Er der nogen der ved hvordan man omskriver bertie's SQLServer løsning til Oracle?
Avatar billede Slettet bruger
05. november 2003 - 22:08 #11
Prøv lige at kigge på hjælpen til Oracle omkring DECODE
Avatar billede Slettet bruger
05. november 2003 - 22:11 #12
Den her er nok bedre http://www.webucator.com/resources/sql/reference.html
Skulle hedde NVL.
Avatar billede el_fredo Praktikant
07. november 2003 - 09:57 #13
Ok. Hvordan ville man så i praksis inkorporere NVL i sætningen:

(SELECT sagspost.medarbejdernummer nr, sum sagspost.antalregistreret) timer FROM test.sagspost WHERE sagspost.posteringsdato BETWEEN '2002.01.01' AND '2003.10.31' AND (sagspost.aktivitetsnummer = '908') GROUP BY sagspost.medarbejdernummer) gruppe5

?

Så jeg ikke får fejl, hvis ikke der er en eneste forekomst af posten '908'...
Avatar billede Slettet bruger
07. november 2003 - 20:11 #14
Jeg aner det ikke, jeg kender ikke oracle, men faldt over linket :-)
Avatar billede el_fredo Praktikant
26. november 2003 - 13:50 #15
Jeg har fundet løsningen. I slutningen af min sql-sætning (se ovenfor) skriver jeg
... = gruppe4.nr(+) AND medarb.nr = gruppe6.nr(+)...
Hvis jeg mellem 4 og 6 tilføjer ... AND medarb.nr = gruppe5.nr(+) virker det, eftersom (+) betyder, at oracle selv sætter tomme null-felter ind, såfremt de ikke eksisterer. Så nemt kan det være. Jeg faldt lige over et link. Tak for hjælpen alle sammen.
Avatar billede el_fredo Praktikant
28. november 2003 - 11:44 #16
Arne_V ved du forresten hvordan man får (+) syntaxen fra Oracle til at virke på samme måde i SQL Server? Jeg har oprettet et spørgsmål med dette emne:

http://www.eksperten.dk/spm/433465
Avatar billede Ny bruger Nybegynder

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.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester