Avatar billede webcreator Nybegynder
27. maj 2005 - 18:57 Der er 41 kommentarer og
1 løsning

Hent poster, grupper på tid, træk 5% dårligste og 5% bedste fra

Hej eksperter.

Jeg ønsker at hente nogle poster ud af min database, som indeholder et timestamp. Pt. gruppere jeg på minut-tiden. Men er det muligt, inden grupperingen, at udelukke 5% af posterne med den bedste løbetid (loebetid) og 5% af posterne med den dårligste løbetid?

Min query indtil nu :

SELECT TESTresults.timestamp, TESTresults.loebeNummer, AVG(TESTresults.loebetid)
FROM TESTresults, TESTejere, TESTnumbers WHERE (timestamp BETWEEN '2004-01-01 00:00:00'
AND '2006-01-01 00:00:00') AND TESTnumbers.loebeNummer = TESTresults.loebeNummer
AND TESTnumbers.ejerId = TESTejere.ejerid
AND TESTnumbers.ejerid = 24
GROUP BY DATE_FORMAT(timestamp, '%Y-%m-%d %H:%i')
ORDER BY timestamp
Avatar billede webcreator Nybegynder
27. maj 2005 - 19:01 #1
Lidt ekstra forklaring til systemet :

Jeg har en række ejere af fx hunde. Disse ligger i TESTejere. Til hver ejer er tilknyttet X antal numre (løbenumre - fx 2 hunde der kan løbe om kap). Ligeledes er der til ejeren tilknyttet X løbe-resultater (i tabellen TESTresults).

Jeg har grupperet på loebetid (på time-tid - ikke på minut-tiden som jeg fejlagtigt skrev før) for at få et gennemsnit af, hvor hurtigt alle hundene til en given ejer løb. Tiden som der grupperes på, udgør faktisk et løb. Et løbenummer havde været smartere, men sådan er den nuværende løsning ikke lavet, og jeg kan ikke få lov at lave det om.
En ejer kan have både 2, 5 og 10 hunde med i løbet (ja ja - overdrivelse fremmer forståelsen ;).

For at få et bedre gennemsnit på en ejers hunde/heste (han/hun har måske haft 10 med i kapløbet), er jeg dog blevet bedt om, at fratrække X % af de bedste tider og X % af de dårligste tider. Det skal i hvertfald være en option de kan vælge. Så jeg mangler bare SQL'en til denne operation :)
Avatar billede arne_v Ekspert
27. maj 2005 - 19:04 #2
hvilken database ?
Avatar billede webcreator Nybegynder
27. maj 2005 - 20:58 #3
MySQL :)
Avatar billede webcreator Nybegynder
27. maj 2005 - 20:58 #4
MySQL Version 4.1 faktisk :)
Avatar billede arne_v Ekspert
27. maj 2005 - 21:02 #5
så tror jeg at der er muligheder !
Avatar billede arne_v Ekspert
27. maj 2005 - 21:07 #6
lad mig første prøve at skitsere ideen med lidt abstrakte data:

n = SELECT COUNT(*) FROM ...

start = 0.05*n
num = 0.90*n

SELECT x.f1,AVG(x.f2)
FROM (SELECT * FROM t1,t2,t3 WHERE t1.a=t2.a AND t2.b=t3.b ORDER BY t1.c LIMIT start,num) x
GROUP BY x.f1
Avatar billede webcreator Nybegynder
27. maj 2005 - 21:56 #7
Det lyder super godt, at det sandsynligvis kan lade sig gøre.
Jeg kan dog ikke, ud fra dit eksempel, se hvordan det kan implementeres i min løsning. Er der tale om subQueries eller hvordan ? Kunne jeg få dig til at gøre det kedelige arbejde for mig, og skrive det ind i mit eksempel? Ved du om der findes noget dokumentation ang. den metode du bruger, eller er det bare simpel matematik?
Avatar billede arne_v Ekspert
27. maj 2005 - 22:18 #8
det et svært uden at kunne test

noget a la

SELECT X.timestamp, X.loebeNummer, AVG(X.loebetid) FROM
(SELECT TESTresults.timestamp, TESTresults.loebeNummer, TESTresults.loebetid
FROM TESTresults, TESTejere, TESTnumbers WHERE (timestamp BETWEEN '2004-01-01 00:00:00'
AND '2006-01-01 00:00:00') AND TESTnumbers.loebeNummer = TESTresults.loebeNummer
AND TESTnumbers.ejerId = TESTejere.ejerid
AND TESTnumbers.ejerid = 24
ORDER BY loebetid LIMIT A,B) X
GROUP BY DATE_FORMAT(timestamp, '%Y-%m-%d %H:%i')
ORDER BY timestamp
Avatar billede webcreator Nybegynder
27. maj 2005 - 22:41 #9
Hvor afslutter du parantesen ved : (SELECT TESTresults.timestamp  ?
Avatar billede arne_v Ekspert
27. maj 2005 - 22:43 #10
) X
Avatar billede webcreator Nybegynder
27. maj 2005 - 22:45 #11
Hm, hvordan søren kunne jeg overse den - Tak :)
Avatar billede arne_v Ekspert
27. maj 2005 - 22:47 #12
jeg ved ikke om den er helt rigtig men det burde være nok til at du kan
finpudse den til dne virker
Avatar billede webcreator Nybegynder
27. maj 2005 - 22:51 #13
X = databasen ? Forstår ikke hvorfor jeg skal skrive DB navnet alene efter LIMIT A, B)
Avatar billede arne_v Ekspert
27. maj 2005 - 22:53 #14
X er et navn vi giver resulatet fra subqueryen
Avatar billede webcreator Nybegynder
27. maj 2005 - 22:55 #15
Så dvs. at det heller ikke er databasens navn her ==> SELECT X.timestamp, X.loebeNummer
?
Avatar billede arne_v Ekspert
27. maj 2005 - 22:59 #16
nej - det er

subquery.feltnavn
Avatar billede webcreator Nybegynder
27. maj 2005 - 23:10 #17
Så det burde virke, hvis jeg bare holder fast i fx 'X' ?
Avatar billede arne_v Ekspert
27. maj 2005 - 23:14 #18
prøv det
Avatar billede webcreator Nybegynder
27. maj 2005 - 23:21 #19
Hm, jeg får en fejl - omkring A, B - hvad er i øvrigt det for nogle variabler?
Avatar billede arne_v Ekspert
27. maj 2005 - 23:25 #20
n = SELECT COUNT(*) FROM ...

A = 0.05*n
B = 0.90*n
Avatar billede webcreator Nybegynder
27. maj 2005 - 23:36 #21
Skal mit count statement se sådan ud ? :

SELECT COUNT(*) FROM TESTresults
WHERE (timestamp BETWEEN '2004-01-01 00:00:00'
AND '2006-01-01 00:00:00') AND TESTnumbers.loebeNummer = TESTresults.loebeNummer
AND TESTnumbers.ejerId = TESTejere.ejerid
AND TESTnumbers.ejerid = 24
GROUP BY DATE_FORMAT(timestamp, '%Y-%m-%d %H:%i')
Avatar billede arne_v Ekspert
28. maj 2005 - 00:04 #22
uden group by og med de andre tabeller tror jeg
Avatar billede webcreator Nybegynder
28. maj 2005 - 00:19 #23
Ja, du har ret.. :)
Avatar billede webcreator Nybegynder
28. maj 2005 - 00:20 #24
Nu begynder jeg også så småt at forstår hvad det er der sker.

...BY loebetid LIMIT A,B) X

Ovenstående svarer til nedenstående, ikke ? :

R BY loebetid LIMIT A,B) AS X
Avatar billede webcreator Nybegynder
28. maj 2005 - 00:23 #25
.. og en ting mere:

Hvis A = 1,2 og B = 10,8, finder MySQL så selv ud af at runde op/ned ?
Avatar billede arne_v Ekspert
28. maj 2005 - 00:23 #26
AS er sikkert tilladt der ja
Avatar billede arne_v Ekspert
28. maj 2005 - 00:27 #27
du skal selv lige afrunde til nærmeste integer
Avatar billede webcreator Nybegynder
28. maj 2005 - 00:59 #28
Findes der en metode på Math, der kan runde op ned? Eller skal jeg bare lige selv skrive koden ?
Avatar billede webcreator Nybegynder
28. maj 2005 - 01:00 #29
Math.Round()  - Never mind :)
Avatar billede webcreator Nybegynder
28. maj 2005 - 01:16 #30
Ser nedenstående forkert ud ? 'n' bliver bare '0'. Men udfører jeg mit SQLStateCount i min database, får jeg et resultat. I øvrigt fejler While-løkken også ved 2. gennemløb. Jeg får fejlen : "Connection must be valid and open".

Det er måske værd at gøre opmærksom på, at jeg bruge min forbindelse længere nede i koden i en anden MySQLCommand instans. Men det skulle vel ikke gøre noget.

MySqlCommand command = new MySqlCommand(SQLStateCount, con);

MySqlDataReader dr;

try
{
    con.Open();
}
catch (MySqlException)
{
    return null;
}

dr = command.ExecuteReader();

double n = 0;

while (dr.Read())
    System.Windows.Forms.MessageBox.Show(dr.GetInt64(0).ToString());
    //n = dr.GetInt32(0);

dr.Close();

n = Math.Round(n);

con.Close();
Avatar billede webcreator Nybegynder
28. maj 2005 - 02:44 #31
Har løst ovenstående problem.
Avatar billede webcreator Nybegynder
28. maj 2005 - 02:48 #32
Jeg tror kun jeg har ét problem tilbage. I mit COUNT statement bliver jeg på en eller anden måde nødt til at lave noget GROUPing. Det resultat jeg får tilbage med alle posterne, er nemlig grupperet. Så pt. får jeg fx 12 poster i Count-statementet, men kun 10 poster i resultat-statementet, da 2 af posterne har sekundtiden 43 og 2 andre har sekundtiden 44. Altså bliver disse 4 poster slået sammen til 2. Og så giver det 10 (10 != 12)
Avatar billede webcreator Nybegynder
28. maj 2005 - 02:58 #33
Jeg har prøvet at gruppere, og dette giver mig 10 poster - hveraf værdien i 2 af dem er 2 (da det jo netop er to tider der er slået sammen). Så jeg kunne fuske, og blot i mit program tælle antallet af returnerede rows. Men det må kunne gøres pænere.
Avatar billede webcreator Nybegynder
28. maj 2005 - 11:54 #34
Jeg har ligget i nat og tænkt lidt, og kom frem til den konklusion, at det faktisk ikke er helt korrekt det der er blevet lavet.
Avatar billede webcreator Nybegynder
28. maj 2005 - 12:10 #35
"Men er det muligt, _inden_ grupperingen, at udelukke 5% af posterne med den bedste løbetid (loebetid) og 5% af posterne med den dårligste løbetid?"

Pt. fjerner vi X% af resultaterne _efter_ grupperingen.
Avatar billede arne_v Ekspert
28. maj 2005 - 13:22 #36
nu har jeg jo hele tiden ville lave subqueryen med LIMIT uden GROUP BY
Avatar billede webcreator Nybegynder
29. maj 2005 - 00:31 #37
Hm, ok. Jamen hvis det kan løse mit problem, så er det da også fint :)
Avatar billede webcreator Nybegynder
29. maj 2005 - 15:36 #38
Men kan det overhovedet lade sig gøre uden GROUP BY? Det skal da i hvertfald på til sidst.
Avatar billede arne_v Ekspert
29. maj 2005 - 16:13 #39
der må skulle GRPUP BY på den yderste SELECT
Avatar billede webcreator Nybegynder
16. juni 2005 - 17:16 #40
Nå, jeg fik det desværre ikke til at virke. Er heller ikke relevant længere. Tak for hjælpen. Smider du et svar, Arne?
Avatar billede arne_v Ekspert
23. juni 2005 - 15:13 #41
ok
Avatar billede webcreator Nybegynder
08. juli 2005 - 02:10 #42
Thanks :)
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
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

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