Gemiddelde van laatste 30 records

Status
Niet open voor verdere reacties.

Laroguz

Gebruiker
Lid geworden
27 mei 2006
Berichten
97
Hallo,

Ik heb in een query een veld met o.a. een Meetwaarde. Daarnaast wil ik in een veld het gemiddelde van de laatste 30 records van die Meetwaarde berekenen. Dus in elke record moet het gemiddelde vanaf dat bewuste record + 29 records terug. Bij de eerste 30 records kan hij dus alleen maar terug tot de eerste en wordt het een gemiddelde van minder records. Het aantal records in de query is per selectie steeds verschillend.
De volgorde van metingen/records is bepaald.
iemand enig idee hoe je zoiets kunt doen?

Ik moet op dezelfde manier trouwens ook de standaard deviatie berekenen.

met vriendelijke groeten
Wim Janssen
 
Anders gezegd.
Kun je in een berekend queryveld in*DAvg («expr»; «domein»; «criteria»)*
of concreter in *DAvg("[Waarde]";"QryCPK";«criteria»)* als criteria de laatste 30 records, terugtellend vanaf het actuele record in de query, definieren?

groeten
Wim Janssen
 
Laatst bewerkt:
Het kan een stuk simpeler, met een subquery. Hierin maak je een selectie van de TOP 30 records, die je gebruikt om in de hoofdselectie te filteren. Dat ziet er ongeveer zo uit:

[SQL]SELECT Tabel1.Groep, Tabel1.Waarde, Tabel1.ID
FROM Tabel1
WHERE (Tabel1.ID In (SELECT TOP 30 id FROM tabel1 AS dupe WHERE dupe.groep=tabel1.groep ORDER BY dupe.id DESC))
ORDER BY Tabel1.Groep, Tabel1.ID DESC;[/SQL]
 
Michel,

Ik heb nog nooit met subquery's gewerkt. Als dit

Code:
SELECT TblKwaliteitsData1.TestId, TblKwaliteitsData1.Soort, TblKwaliteitsData1.Code, TblProducten.Groepsnaam, TblKwaliteitsDataSub.Meting, TblKwaliteitsDataSub.Nummer, TblKwaliteitsDataSub.Waarde, TblKwaliteitsDataSub.Onder, TblKwaliteitsDataSub.Boven
FROM TblProducten RIGHT JOIN (TblKwaliteitsData1 RIGHT JOIN TblKwaliteitsDataSub ON TblKwaliteitsData1.TestId = TblKwaliteitsDataSub.TestIdMeting) ON TblProducten.Code = TblKwaliteitsData1.Code
WHERE (((TblKwaliteitsData1.Soort)="Vrijgavemonster") AND ((TblProducten.Groepsnaam)=[Forms]![FrmKeuzeCPK]![CboProduct]) AND ((TblKwaliteitsDataSub.Meting)=[Forms]![FrmKeuzeCPK]![CboMeting]) AND ((Right([Nummer],1))=0))
ORDER BY TblKwaliteitsData1.TestId;


mijn query is, hoe moet ik dan die subquery hierin verwerken?

Wim
 
Maak er eens een voorbeeldje van; hier alvast een voorbeeldje van mij.
 

Bijlagen

Michel,

Hier een simpel voorbeeld waarbij ik in Query1 in het veld [Gemiddelde] het gemiddelde vanaf dat bewuste record + 29 records terug wil hebben.

groeten
Wim
 

Bijlagen

Ik mis een veld Meting; ik dacht dat je van een bepaald metingtype de laatste 30 records wilde hebben. Utgaande van je voorbeeld is het een stuk simpeler, want eigenlijk wil je een gemiddelde hebben van de laatste 30 records in je tabel. Dat ziet er dan zo uit:

[SQL]SELECT Avg(Waarde) AS Gemiddelde
FROM Waarden
WHERE (Id In (select top 30 t1.ID from waarden t1 order by t1.id desc));
[/SQL]
 
Michel,

Ik denk dat mijn vraagstelling nog niet duidelijk genoeg is.

Ik heb in een query een veld met o.a. een Meetwaarde. Daarnaast wil ik in een veld het gemiddelde van de laatste 30 records van die Meetwaarde berekenen. Dus in elke record moet het gemiddelde vanaf dat bewuste record + 29 records terug. Bij de eerste 30 records kan hij dus alleen maar terug tot de eerste en wordt het een gemiddelde van minder records. Het aantal records in de query is per selectie steeds verschillend.
De volgorde van metingen/records is bepaald.
iemand enig idee hoe je zoiets kunt doen?

Ik wil dus een query die alle records weergeeft en in één veld per record, het gemiddelde van het veld [waarde] en de 29 voorgaande records. Je krijgt dus een query met een soort voortschreidend gemiddelde.

groeten
Wim
 
Dan zou je misschien moeten gaan denken aan een combinatie van een lopend totaal, en een gemiddelde berekening zoals ik eerder gepost heb. Dat maak ik niet zo even tussen neus en lippen door, zul je wel snappen... Daar wil ik dus vanavond wel even naar kijken, zodat de baas ook nog wat aan me heeft.
 
Michel,

Dat zou ik geweldig vinden als je daar naar wilde kijken.

groeten
Wim
 
Ik heb ondertussen geprobeerd om een query in VBA te maken. Als dat lukt kan ik wat meer berekeningen t.a.v. het gemiddelde erop loslaten.
Die query in VBA lukt echter nog niet zo goed. Ik heb op internet gezocht en krijg voornamelijk onderstaande code als oplossing.

Code:
Public Function Query01()

    Dim dbs As Database
    Dim rs As Recordset
    Dim qdf As QueryDef
    Dim MetingNaam As String
    Dim strSql As String

    Set dbs = CurrentDb()

    MetingNaam = "RV"

    strSql = "SELECT [TblKwaliteitsDataSub].* From [TblKwaliteitsDataSub] WHERE [TblKwaliteitsDataSub].Meting = " & Chr(34) & MetingNaam & Chr(34) & ";"

    Set rs = dbs.OpenRecordset(strSql, dbOpenSnapshot)

    With dbs
    Set qdf = .CreateQueryDef("tmpMetingNaam", strSql)
    DoCmd.OpenQuery "tmpMetingNaam"
    .QueryDefs.Delete "tmpMetingNaam"
    End With
    dbs.Close
    qdf.Close
   
End Function

Bij het uitvoeren hiervan, via een knop op een formulier, krijg ik steeds de melding
Compileerfout: Een door de gebruiker gedefinieerd gegevenstype is niet gedefinieerd.
Dit met een highlight op Dim dbs As Database.
Ik werk trouwens met Access 2003 en VBA 6.3

Wat doe ik hier fout?

groeten
Wim
 
Laatst bewerkt:
Je was er dus ook al achter dat het via een query waarschijnlijk niet zou lukken ;) Nou, ik ook :)
Ergo: ik ben ook bezig met een functie die het probleem oplost, en ik moet zeggen: hij is voor 90% klaar. Ik moet nog een paar kleinigheidjes wegpoetsen en dan kan ik 'm posten. Wat er bij jou niet werkt kan ik zo niet zeggen, maar ik vermoed dat er een probleem is met het laden van de juiste bibliotheken. De code is namelijk redelijk standaard, en bepaald niet spectaculair... Je kan eerst dus het beste controleren welke bibliotheken zijn geladen. Om een database te definiëren heb je ofwel ADO 2.8, of DAO 3.6 nodig. Soms zijn ze alletwee geladen, en dan is de volgorde nog belangrijk. Zie plaatje.
 

Bijlagen

  • Verwijzingen.jpg
    Verwijzingen.jpg
    41,6 KB · Weergaven: 22
Ok, we komen verder. Bibliotheken in de juiste volgorde geladen. Nu krijg ik de volgende foutmelding.
Typen komen niet met elkaar overeen.
Dit met een highlight op Set rs = dbs.OpenRecordset(strSql, dbOpenSnapshot)
Wat nu?

groeten
Wim
 
Je kan de variabelen nog expliciet als DAO of ADO declareren, soms helpt dat.
Dus:
Dim db As DAO.Database
Dim rs As DAO.Recordset


Overigens heb ik de oplossing werkend, dus als je het zat bent om het zelf uit te zoeken, dan hoor ik 't wel ;)
 
Michel,

Ik zou zeer dankbaar zijn voor elke andere oplossing. Ik vind het wel leuk om steeds nieuwe dingen in Access uit te zoeken, maar ik ben nu ook in de baas zijn tijd bezig en dat wil ik toch wel een beetje verantwoord houden.

groeten
Wim
 
En de query werkt nu trouwens ook met die expliciete declaratie. Maar dit is nog maar een standaard query, die nog lang niet doet wat mijn eerste vraag was.

dank
Wim
 
Dan is dit denk ik een leuke aanzet.... Overigens werkt deze oplossing (nog) maar één kant op, en misschien wel de verkeerde. Maar dat komt omdat de oorspronkelijke vraagstelling nog een tegenstelling bevatte. Namelijk deze:
Daarnaast wil ik in een veld het gemiddelde van de laatste 30 records van die Meetwaarde berekenen.
Dus je wilt van achteren naar voren steeds 30 records terug. Denk ik dan.
Bij de eerste 30 records kan hij dus alleen maar terug tot de eerste en wordt het een gemiddelde van minder records. Het aantal records in de query is per selectie steeds verschillend.
Hé denk ik nu: impliceer je hier dat bij een groter aantal dan 30 records je het gemiddelde wilt over elke groep van 30 records, en dat de eerste 30 dus ook een gemiddelde moeten krijgen? Want dat zou inhouden dat het restant berekend wordt over minder dan 30 records.....

Oftwel: begin je van voren met berekenen, of van achteren? In het laatste geval worden bij elk nieuw record dat je toevoegt nieuwe gemiddelden berekend, dus alle groepen vanaf record 1. Bij rekenen vanaf record 1 blijven alle groepgemiddelden gelijk, en verandert alleen de laatste groep.

Aan de hand van mijn voorbeeld heb je denk ik in no-time de tweede variant ontwikkeld; ik heb dus de eerste gemaakt. Ook al omdat de tweede variant (over een vast aantal records teruglopen) een heel stuk simpeler is...
 

Bijlagen

Michel,

Ik wil dus inderdaad de volgens jou, denk ik, 2e variant waarbij ik steeds het gemiddelde van de laatste 30 records, terugtellend vanaf de actuele record.
Dus bij de 1e record het gemiddelde van record 1
Bij 2e record het gemiddelde van record 1 en 2
Bij 30e record het gemiddelde van record 1 t/m 30
Bij 32e record het gemiddelde van record 3 t/m 32

De code vraagt trouwens "Object vereist"
met een highlight op Set rs = dbs.OpenRecordset(strSQL, dbOpenSnapshot)

groeten
Wim
 
Die regel moet er uit; die had ik even van jouw voorbeeld gekopieerd om te kijken of ik ook een foutmelding kreeg. Overigens snap ik het nu niet helemaal; als je 54 records hebt, en je wilt het gemiddelde weten van de laatste 30 records, dan valt er toch niks te berekenen voor record 1 t/m 24? Ik begreep, dat als je 12 records had, je bij records 1-12 het gemiddelde wilde zien van die 12 records, en zo oplopend tot er meer dan 30 records zijn, waarna je alleen de laatste 30 records wilt zien. Met dus één gemiddelde.
 
De code doet nu niets meer.

Als ik 54 records heb, moet ik ook 54 gemiddelden hebben.
Bij 1e record het gemiddelde van record 1
Bij 2e record het gemiddelde van record 1 en 2
Bij 3e record het gemiddelde van record 1 t/m 3
Bij 4e record het gemiddelde van record 1 t/m 4
Bij 5e record het gemiddelde van record 1 t/m 5
Bij 6e record het gemiddelde van record 1 t/m 6
Bij 7e record het gemiddelde van record 1 t/m 7
Bij 8e record het gemiddelde van record 1 t/m 8
Bij 9e record het gemiddelde van record 1 t/m 9
Bij 10e record het gemiddelde van record 1 t/m 10
Bij 11e record het gemiddelde van record 1 t/m 11
Bij 12e record het gemiddelde van record 1 t/m 12
Bij 13e record het gemiddelde van record 1 t/m 13
Bij 14e record het gemiddelde van record 1 t/m 14
Bij 15e record het gemiddelde van record 1 t/m 15
Bij 16e record het gemiddelde van record 1 t/m 16
Bij 17e record het gemiddelde van record 1 t/m 17
Bij 18e record het gemiddelde van record 1 t/m 18
Bij 19e record het gemiddelde van record 1 t/m 19
Bij 20e record het gemiddelde van record 1 t/m 20
Bij 21e record het gemiddelde van record 1 t/m 21
Bij 22e record het gemiddelde van record 1 t/m 22
Bij 23e record het gemiddelde van record 1 t/m 23
Bij 24e record het gemiddelde van record 1 t/m 24
Bij 25e record het gemiddelde van record 1 t/m 25
Bij 26e record het gemiddelde van record 1 t/m 26
Bij 27e record het gemiddelde van record 1 t/m 27
Bij 28e record het gemiddelde van record 1 t/m 28
Bij 29e record het gemiddelde van record 1 t/m 29
Bij 30e record het gemiddelde van record 1 t/m 30
Bij 31e record het gemiddelde van record 2 t/m 31
Bij 32e record het gemiddelde van record 3 t/m 32
Bij 33e record het gemiddelde van record 4 t/m 33
Bij 34e record het gemiddelde van record 5 t/m 34
Bij 35e record het gemiddelde van record 6 t/m 35
Bij 36e record het gemiddelde van record 7 t/m 36
Bij 37e record het gemiddelde van record 8 t/m 37
Bij 38e record het gemiddelde van record 9 t/m 38
Bij 39e record het gemiddelde van record 10 t/m 39
enz.

Ik had geloof ik niet gezegd dat het gemakkelijk zou worden :-)

groeten
Wim
 
Status
Niet open voor verdere reacties.
Terug
Bovenaan Onderaan