Avatar billede ogodt Nybegynder
16. august 2005 - 13:10 Der er 13 kommentarer og
1 løsning

Samle/sum af poster i sql

Hej,

Jeg har en Navision Attain database hvor jeg bruger ODBC til at hente data over i Excel/MS query.

I MS query har jeg 2 tabeller med 15 kolonner og dataene der bliver hentet er de rigtige men jeg har følgende problem:

Jeg har følgende felter (hvori problemet ligger)

kalkulationsnr.  Salgsordrenr.  Beløb.
11028              45021            1549
11028              45021            1054
11028              45021            729
11028              45021            6458
11029              45034            2547
11029              45034            5214
11029              45034            134
11029              45034            589

problemet er feltet "Beløb" som indeholder 4 poster per
kalkulationsnr/salgsordrenr, jeg vil gerne have lavet det så
beløb bliver summeret per kalkulationsnr. som følgende:

kalkulationsnr.  Salgsordrenr.  Beløb.
11028              45021            9790
11029              45034            7984

Oplysning: hvis jeg fjerner feltet "beløb" fra forespørgelsen fremkommer der kun en linie pr kalkulationsnr.
så det er kun pga "beløb" at der kommer 4 linier.

Jeg håber der er nogen som kan hjælpe og jeg skal lige nævne at jeg ikke er sql haj..


vh,
Ole
Avatar billede arne_v Ekspert
16. august 2005 - 13:13 #1
SELECT kalkulationsnr,Salgsordrenr,SUM(Beløb.)
FROM tabel
GROUP BY kalkulationsnr,Salgsordrenr

lyder som noget af det rigtige
Avatar billede ogodt Nybegynder
16. august 2005 - 13:33 #2
Jeg har kvajet mig, så her kommer det fulde SQL:

SELECT Efterkalkulationshoved.Efterkalkulationsnr, Efterkalkulationshoved.Salgsordrenr, Efterkalkulationsinier.Beløb, Efterkalkulationshoved.Kundenr, Efterkalkulationshoved.Kundenavn, Efterkalkulationshoved.Varenr, Efterkalkulationshoved."Varebeskrivelse 1", Efterkalkulationshoved."Oprindeligt Bestilt", Efterkalkulationshoved.Antal, Efterkalkulationshoved.Pris, Efterkalkulationshoved."Beløb DKK", Efterkalkulationshoved."Oprettet d_", Efterkalkulationshoved."Oprettet fra Bogført", Efterkalkulationshoved.Varebogf_gruppe, Efterkalkulationshoved.KundeVareKode, Efterkalkulationshoved."Antal Farver", Efterkalkulationshoved."Nettofolie - MM", Efterkalkulationshoved."Brutto Tykkelse1 - MY", Efterkalkulationshoved."Brutto Klasse1", Efterkalkulationshoved."Brutto Tykkelse2 - MY", Efterkalkulationshoved."Brutto Klasse2", Efterkalkulationshoved."Brutto Tykkelse3 - MY", Efterkalkulationshoved."Brutto Klasse3", Efterkalkulationshoved."Antal Baner", Efterkalkulationshoved."Afsnitslængde - MM"
FROM Efterkalkulationshoved Efterkalkulationshoved, Efterkalkulationsinier Efterkalkulationsinier
WHERE Efterkalkulationsinier.Efterkalkulationsnr = Efterkalkulationshoved.Efterkalkulationsnr AND ((Efterkalkulationshoved.Kundenr='11111111') AND (Efterkalkulationshoved."Oprettet d_">{d '2005-06-30'}))
ORDER BY Efterkalkulationshoved.Efterkalkulationsnr

som det står her giver det, det som jeg beskrev i første oplæg altså 4 linier pr.
kalkulationsnr men fjerner jeg Tablen Efterkalkulationsinier kommer den ned på det rigtige (1 linie per efterkalkulationsnr.)

Jeg beklager første oplæg og håber i kan hjælpe

Ole
Avatar billede arne_v Ekspert
16. august 2005 - 13:42 #3
er det ikke samme teknik ?

SUM og GROUP BY
Avatar billede ogodt Nybegynder
16. august 2005 - 13:48 #4
jeg forstår ikke hvad du mener?

Jeg vil gerne summere de 4 linier "Beløb) per kalkulationsnr.
Avatar billede struds Nybegynder
17. august 2005 - 00:16 #5
Som arne_v siger er det SUM og GROUP BY du skal have fat i.

Mener det fulde udtryk bliver:

SELECT Efterkalkulationshoved.Efterkalkulationsnr, Efterkalkulationshoved.Salgsordrenr, SUM(Efterkalkulationsinier.Beløb), Efterkalkulationshoved.Kundenr, Efterkalkulationshoved.Kundenavn, Efterkalkulationshoved.Varenr, Efterkalkulationshoved."Varebeskrivelse 1", Efterkalkulationshoved."Oprindeligt Bestilt", Efterkalkulationshoved.Antal, Efterkalkulationshoved.Pris, Efterkalkulationshoved."Beløb DKK", Efterkalkulationshoved."Oprettet d_", Efterkalkulationshoved."Oprettet fra Bogført", Efterkalkulationshoved.Varebogf_gruppe, Efterkalkulationshoved.KundeVareKode, Efterkalkulationshoved."Antal Farver", Efterkalkulationshoved."Nettofolie - MM", Efterkalkulationshoved."Brutto Tykkelse1 - MY", Efterkalkulationshoved."Brutto Klasse1", Efterkalkulationshoved."Brutto Tykkelse2 - MY", Efterkalkulationshoved."Brutto Klasse2", Efterkalkulationshoved."Brutto Tykkelse3 - MY", Efterkalkulationshoved."Brutto Klasse3", Efterkalkulationshoved."Antal Baner", Efterkalkulationshoved."Afsnitslængde - MM"
FROM Efterkalkulationshoved Efterkalkulationshoved, Efterkalkulationsinier Efterkalkulationsinier
WHERE Efterkalkulationsinier.Efterkalkulationsnr = Efterkalkulationshoved.Efterkalkulationsnr AND ((Efterkalkulationshoved.Kundenr='11111111') AND (Efterkalkulationshoved."Oprettet d_">{d '2005-06-30'}))
GROUP BY Efterkalkulationshoved.Efterkalkulationsnr;
Avatar billede ogodt Nybegynder
17. august 2005 - 08:39 #6
Ahh nu fattede jeg hvad Arne mente :-)

Jeg har prøvet og lave det som "struds" foreslår men den kommer med en fejl:

Column not found: Salgsordrenr

Jeg har også prøvet at koge det ned til kun 5 kolonner for at fjerne fejlmuligheder
med med samme resultat?
Avatar billede struds Nybegynder
17. august 2005 - 16:16 #7
Lyder til at kolonne i Efterkalkulationshoved ikke hedder Salgsordrenr. Check lige stavemåden, så du er sikker på at det bliver stavet rigtigt :)
Avatar billede ogodt Nybegynder
18. august 2005 - 08:25 #8
Nej, desværre er det ikke det, jeg har jo også blot tilskrevt SUM og GROUP By,
Hvis jeg f.eks sletter Salgsordrenr. er det bare den næste på listen den ikke kan finde osv. ?? og den fungerer perfekt hvis jeg fjerner SUM og GROUP BY og det sker hvis jeg bare prøver med enten GROUP BY eller SUM???

Jeg håber der er en der kan hjælpe
Avatar billede kjulius Novice
24. august 2005 - 23:31 #9
Ikke for at være efter dig, men en SQL som den du har lavet ser temmelig uoverskuelig ud. Jeg har derfor prøvet at formatere den lidt og lavet nogle kortere alias for tabellerne. Herefter ser den sådan ud


SELECT
H.Efterkalkulationsnr,
H.Salgsordrenr,
SUM(L.Beløb),
H.Kundenr,
H.Kundenavn,
H.Varenr,
H."Varebeskrivelse 1",
H."Oprindeligt Bestilt",
H.Antal,
H.Pris,
H."Beløb DKK",
H."Oprettet d_",
H."Oprettet fra Bogført",
H.Varebogf_gruppe,
H.KundeVareKode,
H."Antal Farver",
H."Nettofolie - MM",
H."Brutto Tykkelse1 - MY",
H."Brutto Klasse1",
H."Brutto Tykkelse2 - MY",
H."Brutto Klasse2",
H."Brutto Tykkelse3 - MY",
H."Brutto Klasse3",
H."Antal Baner",
H."Afsnitslængde - MM"
FROM Efterkalkulationshoved H, Efterkalkulationsinier L
WHERE L.Efterkalkulationsnr = H.Efterkalkulationsnr
AND ((H.Kundenr='11111111') AND (H."Oprettet d_">{d '2005-06-30'}))
GROUP BY H.Efterkalkulationsnr;

Når man nu ved, at alle felter i SELECT som ikke indgår som den del af en aggregat funktion, skal optræde i GROUP BY funktionen, er det indlysende, at der mangler en del felter her.

GROUP BY
H.Efterkalkulationsnr,
H.Salgsordrenr,
H.Kundenr,
H.Kundenavn,
H.Varenr,
H."Varebeskrivelse 1",
H."Oprindeligt Bestilt",
H.Antal,
H.Pris,
H."Beløb DKK",
H."Oprettet d_",
H."Oprettet fra Bogført",
H.Varebogf_gruppe,
H.KundeVareKode,
H."Antal Farver",
H."Nettofolie - MM",
H."Brutto Tykkelse1 - MY",
H."Brutto Klasse1",
H."Brutto Tykkelse2 - MY",
H."Brutto Klasse2",
H."Brutto Tykkelse3 - MY",
H."Brutto Klasse3",
H."Antal Baner",
H."Afsnitslængde - MM"

GROUP BY er altså ikke en erstatning for ORDER BY, men en nødvendig ekstra funktion, som kommer i spil så snart man begynder at bruge aggregate funktioner (SUM, AVG, COUNT, STDDEV m.m.).
Sorteringen af det returnerede rowset bliver altså stadig styret af ORDER BY.
Avatar billede kjulius Novice
24. august 2005 - 23:54 #10
Nåja, den formattering blev vist ikke helt som jeg havde forestillet mig det, men du kan forhåbentlig alligevel se, hvad det var jeg ville sige.. :-)
Avatar billede ogodt Nybegynder
25. august 2005 - 11:01 #11
kjulius YOU ROCK :-)

Det virker 200 % jeg havde ellers givet op, det eneste der er, er at den kun tillader
20 GROUP BY hvor jeg har ca. 22 men det er småting så hvis du vil sende et svar vil jeg tildele dig point.

Jeg takker
Avatar billede kjulius Novice
25. august 2005 - 20:45 #12
My pleasure!
Avatar billede kjulius Novice
25. august 2005 - 21:03 #13
Forøvrigt, hvis det som i ovenstående tilfælde kun er felter fra en af tabellerne der skal bruge aggregat funktioner, kan den begrænsning omgås ved at lave summeringen i en selvstændig temp tabel:

SELECT
H.Efterkalkulationsnr,
H.Salgsordrenr,
Tmp.TotalValue,
H.Kundenr,
H.Kundenavn,
H.Varenr,
H."Varebeskrivelse 1",
H."Oprindeligt Bestilt",
H.Antal,
H.Pris,
H."Beløb DKK",
H."Oprettet d_",
H."Oprettet fra Bogført",
H.Varebogf_gruppe,
H.KundeVareKode,
H."Antal Farver",
H."Nettofolie - MM",
H."Brutto Tykkelse1 - MY",
H."Brutto Klasse1",
H."Brutto Tykkelse2 - MY",
H."Brutto Klasse2",
H."Brutto Tykkelse3 - MY",
H."Brutto Klasse3",
H."Antal Baner",
H."Afsnitslængde - MM"
FROM Efterkalkulationshoved H, (SELECT Efterkalkulationsnr, SUM(Beløb) AS TotalValue FROM Efterkalkulationsinier GROUP BY Efterkalkulationsnr) AS Tmp
WHERE Tmp.Efterkalkulationsnr = H.Efterkalkulationsnr
AND ((H.Kundenr='11111111') AND (H."Oprettet d_">{d '2005-06-30'}))
ORDER BY H.Efterkalkulationsnr;

På den måde kan du undgå de mange GROUP BY felter. Men som sagt kan det trick kun bruges hvis aggregat felterne kun bruges i den ene tabel og der ikke er andre felter fra denne tabel der ønskes returneret.
Avatar billede kjulius Novice
25. august 2005 - 21:28 #14
Ved nærmere eftertanke kan jeg ikke garantere, at overstående "fix" vil virke. Det kræver, at Efterkalkulationsnr er unikt i tabellen Efterkalkulationshoved. Hvis tabellen indeholder flere rows med samme Efterkalkulationsnr. vil det ikke give samme resultat som den SQL med de mange GROUP BY felter.
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