11. september 2005 - 17:43Der er
34 kommentarer og 1 løsning
Er ikke i en aggregat funktion
Jeg har denne sætning:
SQLstmt = "SELECT SUM(ol.Pris*ol.antal) AS sum, k.Firmanavn AS firmanavn, k.KundeID AS kundeid, o.OrdreID AS OrdreID, o.ordrenr AS Ordrenr, o.ordreDato AS ordredato, o.status AS status FROM kunde AS k, Ordre AS o, Ordrelinie AS ol WHERE FirmaID = " & Session("FirmaID") & " AND o.KundeID = k.KundeID AND DatePart(m, o.Ordredato) = " & md & " AND DatePart(yyyy, o.Ordredato) = " & aar & " AND o.Status = 'FAK' AND o.OrdreID = ol.OrdreID "
Men den fejler i ved k.Firmanavn og giver mig fejlen: Column 'k.KundeID' is invalid in the select list because it is not contained in an aggregate function and there is no GROUP BY clause.
Det gør den også ved de andre... på nær som, hvorfor..
Hvis du ved at der for hver gruppe i din GROUP BY kun er eet firmanavn, har du muligvis overtrådt nogle regler for normalformer i relationelle databaser. Det er ikke ulovligt, men kan være uhensigtsmæssigt.
Men er det tilfældet, og du kan leve med det, kan du skrive
SQLstmt = "SELECT X.TotalSum AS sum, k.Firmanavn AS firmanavn, k.KundeID AS kundeid, o.OrdreID AS OrdreID, o.ordrenr AS Ordrenr, o.ordreDato AS ordredato, o.status AS status FROM kunde AS k Inner Join Ordre AS o On o.KundeID = k.KundeID Inner Join (Select OrdreId, Sum(pris*antal) as TotalSum from OrdreLinie Group By OrdreId) as X On X.ordreId = o.OrdreId WHERE FirmaID = " & Session("FirmaID") & " AND DatePart(m, o.Ordredato) = " & md & " AND DatePart(yyyy, o.Ordredato) = " & aar & " AND o.Status = 'FAK'"
Som arne_v skriver, bør du angive alle andre felter end dem som bruger aggregat funktioner på en GROUP BY:
SELECT SUM(ol.Pris*ol.antal) AS sum, k.Firmanavn AS firmanavn, k.KundeID AS kundeid, o.OrdreID AS OrdreID, o.ordrenr AS Ordrenr, o.ordreDato AS ordredato, o.status AS status FROM kunde AS k, Ordre AS o, Ordrelinie AS ol WHERE FirmaID = " & Session("FirmaID") & " AND o.KundeID = k.KundeID AND DatePart(m, o.Ordredato) = " & md & " AND DatePart(yyyy, o.Ordredato) = " & aar & " AND o.Status = 'FAK' AND o.OrdreID = ol.OrdreID " GROUP BY k.Firmanavn, k.KundeID, o.OrdreID, o.ordrenr, o.ordreDato, o.status
Men er der ikke en anden måde, fordi jeg har tror jeg har fundet fejlen..
det er Sum der er fejl.. Jeg skal rigtig nok have en sum af de tal, men som det er nu ligger den alle tupler sammen, men jeg skal jo i realiteten kører det igennem for hver tuple jeg får ud... Så for hver tuple jeg får skal den finde ud af hvor meget summen er af pris * antal, det den gør nu er vel at ligge det hele sammen for alle tupler....
Sådan her su den rigtige ud, jeg vil bare samle det i en da det er andet er en million år om at kører..
SQLstmt = "SELECT * FROM kunde WHERE FirmaID = " & Session("FirmaID") Set RSKunde = Conn.Execute(SQLstmt) If Not RSKunde.EOF Then Do While Not RSKunde.EOF SQLstmt = "SELECT * FROM Ordre WHERE KundeID = " & RSKunde("KundeID") &" AND DatePart(m, Ordredato) = " & md & " AND DatePart(yyyy, Ordredato) = " & aar & " AND Status = 'FAK' " Set RSOrdre = Conn.Execute(SQLstmt) If Not RSOrdre.EOF Then Do While Not RSOrdre.EOF SQLstmt = "SELECT * FROM Ordrelinie WHERE OrdreID = " & RSOrdre("OrdreID") Set RSOrdrelinie = Conn.Execute(SQLstmt) If Not RSOrdrelinie.EOF Then Do While Not RSOrdrelinie.EOF sum = sum + (RSOrdrelinie("Pris") * RSOrdrelinie("Antal")) RSOrdrelinie.MoveNext Loop Else Response.Write "" End If %> <tr> <td><%= RSKunde("Firmanavn") %></td> <td><a href="default.asp?valg=2&KundeID=<%= RSKunde("KundeID") %>&ordreid=<%= RSOrdre("OrdreID") %>"><%= RSOrdre("Ordrenr") %></a></td> <td><%= RSOrdre("Ordredato") %></td> <td> </td> <td><%= RSOrdre("Status") %></td> <td><%= sum %></td> <td><%= sum * 1.25 %></td> </tr> <% fakbelob = fakbelob + sum sum = 0 RSOrdre.MoveNext Loop Else Response.Write "" End If RSKunde.MoveNext Loop Else Response.Write "" End If %>
"Hvis der ingen ordrelinier er bliver den ikke udskrevet... det skal den jo selvom der ingen linier er".
Det lyder mærkeligt. En ordre uden ordrelinier?
Men så er du nødt til at bruge en left outer join:
SELECT SUM(ol.Pris*ol.antal) AS sum, k.Firmanavn AS firmanavn, k.KundeID AS kundeid, o.OrdreID AS OrdreID, o.ordrenr AS Ordrenr, o.ordreDato AS ordredato, o.status AS status FROM kunde AS k INNER JOIN Ordre AS o ON o.KundeID = k.KundeID LEFT OUTER JOIN Ordrelinie AS ol ON o.OrdreID = ol.OrdreID WHERE FirmaID = " & Session("FirmaID") & " AND DatePart(m, o.Ordredato) = " & md & " AND DatePart(yyyy, o.Ordredato) = " & aar & " AND o.Status = 'FAK' GROUP BY k.Firmanavn, k.KundeID, o.OrdreID, o.ordrenr, o.ordreDato, o.status
Okay, nu bliver det lidt uhyggeligt, synes jeg. Normalt opretter man en ordre, og så en faktura. Uden ordre, ingen faktura. Er en faktura først fremkommet, må man ikke omgøre den, men skal udligne den med en kreditnota. Er det anderledes hos dig, og i givet fald, har du taget din revisor i ed?
Så længe din faktura ikke er gennemført kan du sagtens annullere den. Det ved jeg da at nogle af de største elektronikkæder gør. Så langæe fakturaen ikke er accepterede, så kan den annulleres.
Ja, så længe den ikke er udskrevet, kan den annulleres, men så er det heller ikke i min definition en faktura endnu. Så snart den er udskrevet og tildelt et fakturanummer, må man ikke annullere den eller på anden måde ændre den. Det ville åbne for alle mulige måder at snyde på. Man skal desuden kunne dokumentere en ubrudt række af faktura-numre og må ikke genbruge disse (inden for et regnskabsår, tror jeg).
Ikke at jeg er revisor eller noget i den retning, men det er sådan vore revisorer har forklaret reglerne.
det er rigtigt nok, men så længe kunden ikke har fået faktura'en, kan den jo stadig have et fakturanummer, og kan sagtens annulleres, mens hvis kunden har fået den er der ingen vej udenom... ;-)
Tja, tjo, men det åbner stadig for større muligheder for svindel, hvis man har en papirfaktura liggende, som ikke er det samme som det der optræder i regnskabet. Hvis den ved en fejl blev sendt til modtageren og denne ikke havde en ordentlig kontrol?
Fra et sikkerhedsperspektiv er det meget bedre at lukke for den mulighed.
Måske er det nødvendigt at omdanne en evt. null værdi med værdien 0 (kan opstå hvis der ingen ordrelinier findes til en ordre).
SELECT SUM(ISNULL(ol.Pris, 0) * ISNULL(ol.antal, 0)) AS sum, k.Firmanavn, k.KundeID, o.OrdreID, o.ordrenr, o.ordreDato, o.status FROM kunde AS k INNER JOIN Ordre AS o ON o.KundeID = k.KundeID LEFT OUTER JOIN Ordrelinie AS ol ON o.OrdreID = ol.OrdreID WHERE FirmaID = " & Session("FirmaID") & " AND DatePart(m, o.Ordredato) = " & md & " AND DatePart(yyyy, o.Ordredato) = " & aar & " AND o.Status = 'FAK' GROUP BY k.Firmanavn, k.KundeID, o.OrdreID, o.ordrenr, o.ordreDato, o.status
Hvis den returnerer noget, men det ikke er det du ønsker, må du lige sige hvor det går galt - altså hvad du ønsker, for det er ikke helt klart for mig.
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.