Avatar billede oz0j Nybegynder
26. august 2003 - 08:30 Der er 19 kommentarer og
1 løsning

SQL - sum af kolonner

Jeg har en tabel, hvor jeg via en SQL forespørgsel skal bruge en sum i en kolonne.

Mit problem er, at alle tallene i den kolonne, der skal summes, er positive. Nogle af dem skal trækkes fra i stedet.

Min forspørgsel er følgende:

select medarbejderkode, sum(timer) as timer
from fravarsposter
where fravarskode = 70
and dato >= '05-01-2003'
and art in (1,3)
group by medarbejderkode
union
select medarbejderkode, sum(timer)*-1 as timer
from fravarsposter
where fravarskode = 70
and dato >= '05-01-2003'
and art not in (1,3)
group by medarbejderkode
order by medarbejderkode

Den giver følgende resultat:

medarbejderkode      timer               
-------------------- ---------------------
50002                -33.3000
50002                37.0000
50060                -37.0000
50060                37.0000
osv.

Jeg skal bruge følgende resultat:

medarbejderkode      timer               
-------------------- ---------------------
50002                    3,70
50060                    0,00
osv.

Der må gerne være delsumskolonner imellem, før eller efter, bare jeg får dette resultat. Nogen forslag?

mvh
Jørgen Rømming
Avatar billede arne_v Ekspert
26. august 2003 - 08:34 #1
Hvis du bare laver en SUM(timer) GROUP BY medarbejderkode uden den
UNION får du så ikke præcis det du vil ?
Avatar billede arne_v Ekspert
26. august 2003 - 08:35 #2
select medarbejderkode, sum(timer) as timer
from fravarsposter
where fravarskode = 70
and dato >= '05-01-2003'
group by medarbejderkode
Avatar billede oz0j Nybegynder
26. august 2003 - 08:46 #3
i princippet jo. men så er mit problem, at de "timer" der ikke har art 1 og 3 (se ovenfor) LÆGGES TIL i stedet for at blive trukket fra.
Dvs. at den så sammenlægger 33,3 og 37, hvilket giver 70,30. Resultatet skulle jo gerne give 3,7 (for første medarbejder).
jeg skal have vendt fortegnet på nogle af timerne, INDEN de lægges sammen
Avatar billede arne_v Ekspert
26. august 2003 - 09:33 #4
Hm.

Det kan jeg godt se.

Hvad med:

create view justeret_fravarsposter as
((select medarbejderkode, timer, fravarskode, dato
from fravarsposter
where art in (1,3))
union
(select medarbejderkode, sum(timer)*-1 as timer, fravarskode, dato
from fravarsposter
where art not in (1,3)))

og:

select medarbejderkode, sum(timer) as timer
from justeret_fravarposter
where fravarskode = 70
and dato >= '05-01-2003'
group by medarbejderkode
order by medarbejderkode
Avatar billede oz0j Nybegynder
26. august 2003 - 10:31 #5
jeg rettede et par småting i dit script og så virker det.

Næste problem er, at justeret_fravarsposter ikke danner alle poster. Jeg har følgende poster:

30-05-03    7,40    ok
05-06-03    3,70   
06-06-03    7,40    ok
13-06-03    7,40    ok
19-07-03    7,40    ok
31-05-03    7,40    ok
31-05-03    7,40   
31-05-03    -7,40    ok
31-05-03    29,60    ok
31-05-03    -29,60    ok
31-05-03    29,60   
31-05-03    -29,60   
31-05-03    29,60   
31-05-03    -29,60   
31-05-03    29,60   

OK er dem, der er dannet i justeret_fravarsposter. Ingen "ok" er dem, der kun findes i lønmodulet. Alle poster opfylder kriterierne så....

Hvordan "nulstiller" / sletter jeg et create view? Jeg vil gerne kunne genbruge justeret_fravarsposter i næste måned.
Avatar billede arne_v Ekspert
26. august 2003 - 10:38 #6
Et view er dynamisk d.v.s at hvis du tilføjer til eller retter
i original data så opdateres data i view automatisk.
Avatar billede arne_v Ekspert
26. august 2003 - 10:39 #7
Det med OK og ikke-OK forstod jeg ikke.
Avatar billede oz0j Nybegynder
26. august 2003 - 10:46 #8
ok betyder at posten "kopieret" fra fravarsposter til justeret_fravarsposter ikke-OK betyder, at posten ikke er kopieret. dvs. at justeret_fravarsposter har ikke alle poster fra fravarsposter med. og så er jeg ligevidt.
Avatar billede arne_v Ekspert
26. august 2003 - 10:48 #9
Er der records hvor art er NULL ?
Avatar billede oz0j Nybegynder
26. august 2003 - 10:56 #10
jah - måske. der er records hvor art = 0 det lyder som om, det er et problem
Avatar billede arne_v Ekspert
26. august 2003 - 11:00 #11
ikke 0 men NULL.

0 burde ikke vær enoget problem. NULL kunne være et problem.
Avatar billede arne_v Ekspert
26. august 2003 - 11:01 #12
Du kunne prøve med:

where (art not in (1,3)) OR (art IS NULL)
Avatar billede oz0j Nybegynder
26. august 2003 - 11:02 #13
hvis jeg kører følgende:

select medarbejderkode, timer, dato, art
from fravarsposter
where art is null

får jeg ingen poster

så svaret må være nej
Avatar billede arne_v Ekspert
26. august 2003 - 11:04 #14
Hm.

Så er jeg lidt blank med hensyn til hvorfor de records ikke kommer med.
Avatar billede oz0j Nybegynder
26. august 2003 - 11:33 #15
også jeg måske en anden kan komme med et godt forslag.
Avatar billede kichian Nybegynder
31. august 2003 - 12:09 #16
Når jeg umiddelbart ser på dine tal, så er der da overensstemmelse! Hvorfor har du ikke medarbejderkode med i <26/08-2003 10:31:50>?

Når du skriver lønmodulet, mener du så fravarsposter?
Avatar billede blackthorne Nybegynder
23. september 2003 - 23:11 #17
hvad med

select medarbejderkode, sum(timer) as timer
from
(
select medarbejderkode, sum(timer) as timer
from fravarsposter
where fravarskode = 70
and dato >= '05-01-2003'
and art in (1,3)
group by medarbejderkode
union
select medarbejderkode, sum(timer)*-1 as timer
from fravarsposter
where fravarskode = 70
and dato >= '05-01-2003'
and art not in (1,3)
group by medarbejderkode)
tabelX
order by medarbejderkode
Avatar billede oz0j Nybegynder
24. september 2003 - 13:47 #18
til kichian <31/08-2003 12:09:03>

medarbejderkoden viste jeg ikke, fordi den var i denne sammenhæng irrelevant.

Der er nemlig ikke overensstemmelse.

I mit svar af <26/08-2003 10:31:50> er de poster, der IKKE er mærket OK, IKKE med i den SQL, der er foreslået af arne V <26/08-2003 09:33:31>

til blackthone <23/09-2003 23:11:31>
den giver følgende fejl:

Column 'tabelX.medarbejderkode' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
Avatar billede oz0j Nybegynder
24. september 2003 - 13:49 #19
Jeg har fået følgende løsning, der virker:

Select t1.medarbejderkode, T1.timer+T2.timer from (
select medarbejderkode, sum(timer) as timer
from fravarsposter
where fravarskode = 70
and dato >= '05-01-2003'
and art in (1,3)
group by medarbejderkode) T1,
(select medarbejderkode, sum(timer)*-1 as timer
from fravarsposter
where fravarskode = 70
and dato >= '05-01-2003'
and art not in (1,3)
group by medarbejderkode) T2
where T1.medarbejderkode=T2.medarbejderkode
order by T1.medarbejderkode
Avatar billede blackthorne Nybegynder
24. september 2003 - 18:50 #20
"Column 'tabelX.medarbejderkode' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause."

Det kunne du nemt løse ved at group by igen på medarbejderkode som her, så skal du ikke lave 2 derived tabels og manuel summer timerne.

select medarbejderkode, sum(timer) as timer
from
(
select medarbejderkode, sum(timer) as timer
from fravarsposter
where fravarskode = 70
and dato >= '05-01-2003'
and art in (1,3)
group by medarbejderkode
union
select medarbejderkode, sum(timer)*-1 as timer
from fravarsposter
where fravarskode = 70
and dato >= '05-01-2003'
and art not in (1,3)
group by medarbejderkode)
tabelX
group by medarbejderkode
order by medarbejderkode
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
Computerworld tilbyder specialiserede kurser i database-management

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