Avatar billede ttopholm Nybegynder
11. september 2005 - 17:43 Der 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..
Avatar billede arne_v Ekspert
11. september 2005 - 17:47 #1
de ting man skal selecter skal enten være en aggregeret funktion eller
også optræde i en GROUP BY

det er det eneste som giver logisk mening
Avatar billede erikjacobsen Ekspert
11. september 2005 - 17:51 #2
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

  max(k.Firmanavn)
Avatar billede arne_v Ekspert
11. september 2005 - 18:04 #3
jeg ville nok bare sætte GROUP BY på hele molevitten
Avatar billede claesdamlund Nybegynder
11. september 2005 - 18:16 #4
Prøv denne:

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'"
Avatar billede ttopholm Nybegynder
11. september 2005 - 20:45 #5
Der kan sagtens være flere firmanavne, men den brokker sig med alle kolonnerne på nær sum
Avatar billede kjulius Novice
11. september 2005 - 22:06 #6
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
Avatar billede ttopholm Nybegynder
11. september 2005 - 22:32 #7
Så viser den dem slet ikke...
Avatar billede kjulius Novice
11. september 2005 - 22:38 #8
Du får intet?
Fejlmeldinger?
Avatar billede ttopholm Nybegynder
11. september 2005 - 22:41 #9
Nej.. Den udskriver dem ikke
Avatar billede ttopholm Nybegynder
11. september 2005 - 22:44 #10
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....
Avatar billede ttopholm Nybegynder
11. september 2005 - 22:46 #11
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>&nbsp;</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
            %>
Avatar billede ttopholm Nybegynder
11. september 2005 - 22:46 #12
Som i kan se er den ikke special optimal...
Avatar billede ttopholm Nybegynder
11. september 2005 - 22:47 #13
Og har også fundet en fejl mere i den samlet..

Hvis der ingen ordrelinier er bliver den ikke udskrevet... det skal den jo selvom der ingen linier er
Avatar billede arne_v Ekspert
11. september 2005 - 22:48 #14
det er jo netop det GROUP BY gør - beregner en aggregeret værdi for hver "gruppe"
Avatar billede kjulius Novice
11. september 2005 - 22:50 #15
Tupler???? Que?
Avatar billede kjulius Novice
11. september 2005 - 23:04 #16
"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
Avatar billede ttopholm Nybegynder
11. september 2005 - 23:11 #17
Tupler er resultater

Man kan jo have oprettet en faktura, men fundet ud af det er fejl, hvorefter man annullere den, uden at have tilføjet ordrelinier
Avatar billede kjulius Novice
11. september 2005 - 23:18 #18
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?
Avatar billede ttopholm Nybegynder
12. september 2005 - 10:20 #19
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.
Avatar billede kjulius Novice
12. september 2005 - 12:41 #20
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.
Avatar billede ttopholm Nybegynder
12. september 2005 - 12:51 #21
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... ;-)
Avatar billede kjulius Novice
12. september 2005 - 12:57 #22
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.
Avatar billede ttopholm Nybegynder
12. september 2005 - 13:21 #23
Ja.. det er rigtigt..
Avatar billede kjulius Novice
12. september 2005 - 13:29 #24
Men for nu at komme tilbage til din SQL, har du så fået den til at virke?
Avatar billede ttopholm Nybegynder
12. september 2005 - 13:42 #25
Nope... Ikke endnu
Avatar billede kjulius Novice
12. september 2005 - 18:35 #26
???, hvad er problemet?

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.
Avatar billede ttopholm Nybegynder
12. september 2005 - 18:38 #27
Det eksempel jeg har ovnfor hvor de er i hver sin sætning skal bare sættes sammen i en.
Avatar billede kjulius Novice
12. september 2005 - 18:45 #28
Jo, men f.eks. fakbeløb som bliver opsummeret for hver kunde bruges jo åbenbart ikke. Er det vigtigt at få med?

Ellers kan jeg ikke se, at der skulle være noget problem. De tre SQL bliver jo sat sammen, sådan at du får et beløb pr. ordre, eller hvad?

Eller vil du have os til at ændre din VBScript kode, så den returnerer det samme som dit nuværende, men med brug af den nye SQL?

Som jeg forstår dit indledende spørgsmål er det kun SQL'en du var interesseret i...
Avatar billede ttopholm Nybegynder
12. september 2005 - 19:28 #29
faktbeløb bliver brugt senere..

Men jeg vil bare have at din giver mig summen, firmanavn, kundeid , ordredato, ordreid, ordrenr og status ud
Avatar billede ttopholm Nybegynder
12. september 2005 - 19:28 #30
og det burde sql give mig.. så kan jeg sagtens udskrive det...
Avatar billede kjulius Novice
12. september 2005 - 20:58 #31
Ja, måske noget á la dette?:

            SQLstmt = "SELECT SUM(ISNULL(ol.Pris, 0) * ISNULL(ol.antal, 0)) AS sum, k.Firmanavn, k.KundeID, o.OrdreID, o.ordrenr, o.ordreDato, o.status" & vbCrLf & _
            "FROM kunde AS k" & vbCrLf & _
            "INNER JOIN Ordre AS o ON o.KundeID = k.KundeID" & vbCrLf & _
            "LEFT OUTER JOIN Ordrelinie AS ol ON o.OrdreID = ol.OrdreID"  & vbCrLf & _
            "WHERE FirmaID = " & Session("FirmaID") & vbCrLf & _
            "  AND DatePart(m, o.Ordredato) = " & md & vbCrLf & _
            "  AND DatePart(yyyy, o.Ordredato) = " & aar & vbCrLf & _
            "  AND o.Status = 'FAK'" & vbCrLf & _
            "GROUP BY k.Firmanavn, k.KundeID, o.OrdreID, o.ordrenr, o.ordreDato, o.status"
            Set rs = Conn.Execute(SQLstmt)
            If Not rs.EOF Then
            Do While Not rs.EOF
            <tr>
            <td><%= rs("Firmanavn") %></td>
            <td><a href="default.asp?valg=2&KundeID=<%= rs("KundeID") %>&ordreid=<%= rs("OrdreID") %>"><%= rs("Ordrenr") %></a></td>
            <td><%= rs("Ordredato") %></td>
            <td>&nbsp;</td>
            <td><%= rs("Status") %></td>
            <td><%= rs("sum") %></td>
            <td><%= rs("sum") * 1.25 %></td>
            </tr>
            <%
            fakbelob = fakbelob + sum
            rs.MoveNext
            Loop
            Else
            Response.Write ""
            End If
            %>
Avatar billede kjulius Novice
12. september 2005 - 21:02 #32
Ja, måske noget á la dette?:

            SQLstmt = "SELECT SUM(ISNULL(ol.Pris, 0) * ISNULL(ol.antal, 0)) AS sum, k.Firmanavn, k.KundeID, o.OrdreID, o.ordrenr, o.ordreDato, o.status" & vbCrLf & _
            "FROM kunde AS k" & vbCrLf & _
            "INNER JOIN Ordre AS o ON o.KundeID = k.KundeID" & vbCrLf & _
            "LEFT OUTER JOIN Ordrelinie AS ol ON o.OrdreID = ol.OrdreID"  & vbCrLf & _
            "WHERE FirmaID = " & Session("FirmaID") & vbCrLf & _
            "  AND DatePart(m, o.Ordredato) = " & md & vbCrLf & _
            "  AND DatePart(yyyy, o.Ordredato) = " & aar & vbCrLf & _
            "  AND o.Status = 'FAK'" & vbCrLf & _
            "GROUP BY k.Firmanavn, k.KundeID, o.OrdreID, o.ordrenr, o.ordreDato, o.status"
            Set rs = Conn.Execute(SQLstmt)
            If Not rs.EOF Then
            Do While Not rs.EOF
            <tr>
            <td><%= rs("Firmanavn") %></td>
            <td><a href="default.asp?valg=2&KundeID=<%= rs("KundeID") %>&ordreid=<%= rs("OrdreID") %>"><%= rs("Ordrenr") %></a></td>
            <td><%= rs("Ordredato") %></td>
            <td>&nbsp;</td>
            <td><%= rs("Status") %></td>
            <td><%= rs("sum") %></td>
            <td><%= rs("sum") * 1.25 %></td>
            </tr>
            <%
            fakbelob = fakbelob + rs("sum")
            rs.MoveNext
            Loop
            Else
            Response.Write ""
            End If
            %>
Avatar billede kjulius Novice
12. september 2005 - 21:04 #33
Ovenstående ikke testet, mangler i hvert fald en %> efter Do While Not rs.EOF
Avatar billede ttopholm Nybegynder
19. december 2005 - 02:15 #34
smid et svar kjulius
Avatar billede kjulius Novice
20. december 2005 - 00:16 #35
Okey doke...
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