[MySQL 3.23] Probleem met MIN()?

Pagina: 1
Acties:

  • BetuweKees
  • Registratie: Januari 2003
  • Laatst online: 15-05 20:44

BetuweKees

Flipje uit Tiel

Topicstarter
Zit met volgende: Probeer uit database een minimale waarde te selecteren, maar dit gaat ergens fout; de minimale waarde die ik terug krijg is in werkerlijkheid namelijk niet de laagste. (zie onderstaande twee queries).
Heb met EXPLAIN de queries al vergeleken; deze spreken de tabel op precies dezelfde manier aan.
Ook komt deze minimale waarde maar een keer voor in de tabel, het lijkt me dus niet dat de database zich verslikt in een duplicate.
Ik neem daarnaast aan dat de bijna 20.000 entries in tijd_overzicht geen probleem mogen zijn..

Waar dit dan wel aan ligt snap ik niet, wellicht dat iemand me kan helpen?


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
SELECT 
    MIN(tijd) AS tijd, 
    leden.leden_id, 
    leden.voornaam 
FROM 
    tijd_overzicht 
    LEFT JOIN tijd_verbinding ON tijd_overzicht.verbinding_id = tijd_verbinding.verbinding_id 
    LEFT JOIN leden ON tijd_overzicht.leden_id = leden.leden_id 
WHERE 
    NOT tijd = '0.00' 
GROUP BY 
    afstand_id;
    
+--------+----------+----------+
| tijd   | leden_id | voornaam |
+--------+----------+----------+
|  10.25 |       36 | Berry    |
+--------+----------+----------+



SELECT 
    MIN(tijd) AS tijd, 
    leden.leden_id, 
    leden.voornaam 
FROM 
    tijd_overzicht 
    LEFT JOIN tijd_verbinding ON tijd_overzicht.verbinding_id = tijd_verbinding.verbinding_id 
    LEFT JOIN leden ON tijd_overzicht.leden_id = leden.leden_id 
WHERE 
    NOT tijd = '0.00' 
    [b]AND tijd = '10.25'[/b] 
GROUP BY 
    afstand_id;
    
+-------+----------+----------+
| tijd  | leden_id | voornaam |
+-------+----------+----------+
| 10.25 |      239 | Rob      |
+-------+----------+----------+

[ Voor 5% gewijzigd door BetuweKees op 13-12-2003 19:50 ]

Through meditation I program my heart to beat breakbeats and hum basslines on exhalation -Blackalicious || *BetuweKees was AFK; op de fiets richting China en verder


  • SuperRembo
  • Registratie: Juni 2000
  • Laatst online: 20-08-2025
Zijn er via die tijd_verbinding tabel meerdere leden met die tijd? Word je hier wijzer mee?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT 
    tijd, 
    leden.leden_id, 
    leden.voornaam 
FROM 
    tijd_overzicht 
    LEFT JOIN tijd_verbinding ON tijd_overzicht.verbinding_id = tijd_verbinding.verbinding_id 
    LEFT JOIN leden ON tijd_overzicht.leden_id = leden.leden_id 
WHERE 
    NOT tijd = '0.00' 
    AND tijd = '10.25'
ORDER BY tijd DESC
LIMIT 100

| Toen / Nu


  • Annie
  • Registratie: Juni 1999
  • Laatst online: 25-11-2021

Annie

amateur megalomaan

Wat is het probleem? Dat je niet de minimale tijd terugkrijgt of dat de voornaam en leden_id niet klopt?
In het eerste geval denk ik dat je eens moet kijken naar een 'kale' query zonder alle joins. Wat krijg je dan terug?
In het tweede geval zal je een andere oplossing moeten kiezen. Wat je hier doet is namelijk onzin ;) Het leden_id is voor zover ik kan zien niet gerelateerd aan de minimale tijd (je groepeerd immers op afstand_id).

Today's subliminal thought is:


  • BetuweKees
  • Registratie: Januari 2003
  • Laatst online: 15-05 20:44

BetuweKees

Flipje uit Tiel

Topicstarter
SuperRembo schreef op 13 december 2003 @ 23:11:
Zijn er via die tijd_verbinding tabel meerdere leden met die tijd?
Zoals ik in mijn TS al schreef is dat niet het geval
Annie schreef op 14 december 2003 @ 00:16:
Wat is het probleem? Dat je niet de minimale tijd terugkrijgt of dat de voornaam en leden_id niet klopt?
Het tweede; het leden_id klopt niet met MIN(tijd)
In het tweede geval zal je een andere oplossing moeten kiezen. Wat je hier doet is namelijk onzin ;) Het leden_id is voor zover ik kan zien niet gerelateerd aan de minimale tijd (je groepeerd immers op afstand_id).
Ik weet niet zeker of ik je hier snap.
Het is echter wel zo dat deze query zonder de joins ook geen zin heeft; maar als je een mogelijke oplossing weet sta ik daar natuurlijk voor open.
Om een en ander nog wat beter te illustreren: Het gaat hier op drie tabellen; de eerste, tijd_overzicht, bevat oa een grote lijst met tijden (tijd), een ref naar de persoon die de tijd reed (leden_id), en een ref naar meer informatie over de tijd (verbinding_id).
tijd_verbinding bevat zoals gezegd meer informatie over de afstand, primary is verbinding_id, en bevat daarnaast oa een ref naar afstands informatie, afstand_id.
tijd_leden spreek voor zich neem ik aan.. :)

De structuur zou er dus ongeveer zo uitzien (irrelevante velden weggelaten)
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
EXPLAIN tijd_overzicht;
+---------------+-----------------------+
| Field         | Type                  |
+---------------+-----------------------+
| tijd_id       | mediumint(8) unsigned |
| leden_id      | smallint(5) unsigned  |
| verbinding_id | smallint(5) unsigned  |
| tijd          | float(8,2) unsigned   |
+---------------+-----------------------+


EXPLAIN leden;
+--------------+--------------------------------+
| Field        | Type                           |
+--------------+--------------------------------+
| leden_id     | smallint(5) unsigned           |
| voornaam     | varchar(64)                    |
+--------------+--------------------------------+


EXPLAIN tijd_verbinding;
+----------------+----------------------+
| Field          | Type                 |
+----------------+----------------------+
| verbinding_id  | smallint(5) unsigned |
| afstand_id     | tinyint(3) unsigned  |
+----------------+----------------------+



Aangezien de snelste tijd natuurlijk per afstand gaat, dus een GROUP BY op afstand_id; lijkt mij logisch, toch :?


[later]
hmm.. loop nu eens even te testen wat er gebeurd wanneer ik de GROUP BY verander; wanneer ik groepeer op leden_id pakt ie wel de juist tijd en persoon bij elkaar, maar krijg ik er meteen de pr's van iedere persoon bij. Wel beter, maar nog steeds niet helemaal..
Is het mogelijk om er voor te zorgen dat voor iedere afstand_id slechts de eerste tijd wordt weergegeven?

Through meditation I program my heart to beat breakbeats and hum basslines on exhalation -Blackalicious || *BetuweKees was AFK; op de fiets richting China en verder


  • SuperRembo
  • Registratie: Juni 2000
  • Laatst online: 20-08-2025
BetuweKees schreef op 14 december 2003 @ 02:26:
[...]Zoals ik in mijn TS al schreef is dat niet het geval[...]
Die Berry en Rob komen niet uit het niets lijkt me, die moeten toch een link hebben met die tijd.
Als je groepeert op afstand_id lijkt het me ook handig om de afstand in de select op te nemen, dan zie je tenminste bij welke afstanden de tijden horen die je vindt. Verder zou ik er inner joins van maken, aan een tijd zonder bijbehorend lid en/of aftand heb je toch niets (en zou niet voor mogen komen).

| Toen / Nu


  • BetuweKees
  • Registratie: Januari 2003
  • Laatst online: 15-05 20:44

BetuweKees

Flipje uit Tiel

Topicstarter
SuperRembo schreef op 14 december 2003 @ 11:59:
Die Berry en Rob komen niet uit het niets lijkt me, die moeten toch een link hebben met die tijd.
Dat leek mij dus ook, maar ik kan er dus *geen* verband tusen vinden..

De reden dat ik bij deze query de afstand_id heb weggelaten is omdat ik in eerste instantie dacht dat het wellicht het probleem duidelijker zou illustreren. Overigens is het zo dat beide tijden een 100 meter betreffen (kleinste afstand die mogelijk is, dus ook laagste tijd die mogelijk is), en de afstand_id voor beide gelijk is..

Ik ga eens kijken of het verschil uitmaakt wanneer ik een INNER JOIN gebruik..


[edit]
Net even flink lopen testen, met 'kale' sorteer query, een GROUP BY op leden_id en afstand_id en een GROUP BY enkel op afstand_id.
Enige wat me opvalt is dat de ranglijst in deze volgorde steeds slechter wordt. Dacht dat wellicht tijd_id en verbinding_id hier voor zorgden aangezien in elke serie bij een opvolgende query steeds lager zijn, maar een van de laatste series spreek dit tegen (afstand_id = 6)
Voor het geval iemand hier wijs uit kan worden heb ik de output file op de webserver gezet; http://www.skits.nl/upload/output.txt

[ Voor 29% gewijzigd door BetuweKees op 14-12-2003 14:50 ]

Through meditation I program my heart to beat breakbeats and hum basslines on exhalation -Blackalicious || *BetuweKees was AFK; op de fiets richting China en verder


  • SuperRembo
  • Registratie: Juni 2000
  • Laatst online: 20-08-2025
Zo vind je de minimum tijd voor elke afstand:
SQL:
1
2
3
4
5
6
7
8
9
10
11
SELECT 
    MIN(to.tijd),
    to.afstand_id
FROM tijd_overzicht to
    INNER JOIN tijd_verbinding tv ON tv.verbinding_id = to.verbinding_id
WHERE
    to.tijd > 0
GROUP BY
    to.afstand_id
ORDER BY
    to.afstand_id ASC


Zo vind je bij een minimum tijd en een afstand de leden die die tijd hebben gehaald:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
SELECT 
    to.tijd,
    l.leden_id,
    l.voornaam,
    to.afstand_id
FROM tijd_overzicht to
    INNER JOIN leden l ON l.leden_id = to.leden_id
    INNER JOIN tijd_verbinding tv ON tv.verbinding_id = to.verbinding_id
WHERE
    (to.tijd = 10.25 )
    AND (to.afstand_id = 1)
ORDER BY
    l.voornaam DESC


Het probleem met jouw query's is dat je kolomen selecteerd die je niet in de group by hebt staan. In MySql mag je kolommen weglaten in de group by, MAAR: (MySql manual) "Don't use this feature if the columns you omit from the GROUP BY part aren't unique in the group! You will get unpredictable results."

| Toen / Nu


  • BetuweKees
  • Registratie: Januari 2003
  • Laatst online: 15-05 20:44

BetuweKees

Flipje uit Tiel

Topicstarter
hmm.. dat van die unpredictable results merk ik ja..

zat zelf ook al sterk te denken het ander maar met meerdere queries op te lossen, maar erg vervelend wel dat dit niet niet netjes in query kan..

helaas.. maar iig zeker bedankt voor je hulp.. :/

Through meditation I program my heart to beat breakbeats and hum basslines on exhalation -Blackalicious || *BetuweKees was AFK; op de fiets richting China en verder


  • BetuweKees
  • Registratie: Januari 2003
  • Laatst online: 15-05 20:44

BetuweKees

Flipje uit Tiel

Topicstarter
nu eindelijk tijd om dit te gaan verbeteren, druk.. :(

toch nog even een vraagje wat me zojuist te binnen schoot..
als ik die tweede query doe, is het dan slimmer om voor iedere afstand apart de details uit te vragen, of een grote query te maken met een berg ANDs en ORs?
maakt dat iets uit voor de performance? 15 keer een losse query of 1 keer een mega grote AND/OR query?

Through meditation I program my heart to beat breakbeats and hum basslines on exhalation -Blackalicious || *BetuweKees was AFK; op de fiets richting China en verder


  • BetuweKees
  • Registratie: Januari 2003
  • Laatst online: 15-05 20:44

BetuweKees

Flipje uit Tiel

Topicstarter
dit is niet leuk meer.. :'(

nu gaat mysql ook nog eens een keer zeggen dat hij tijden niet meer kan vinden..
code:
1
2
3
4
5
6
SELECT 
    * 
FROM 
    tijd_overzicht 
WHERE 
    tijd = '11.52';

geef niets terug terwijl die tijd wel degelijk bestaat!! hellupp.. :X :?

Through meditation I program my heart to beat breakbeats and hum basslines on exhalation -Blackalicious || *BetuweKees was AFK; op de fiets richting China en verder


  • SuperRembo
  • Registratie: Juni 2000
  • Laatst online: 20-08-2025
Dat heeft er mee te maken dat de binaire representatie van 11.52 niet exact is.
SQL:
1
2
3
SELECT *
FROM tijd_overzicht
WHERE tijd BETWEEN 11.515 AND 11.525

zal 'm wel vinden. Het is een FLOAT column, dus geen quotes om de getallen. Misschien dat 't op een makkelijkere manier kan, met round ofzo.

| Toen / Nu


  • BetuweKees
  • Registratie: Januari 2003
  • Laatst online: 15-05 20:44

BetuweKees

Flipje uit Tiel

Topicstarter
ahh.. dus dat is dat currency verhaal waar ik een tijd geleden over las.... dan zou je dus eigenlijk moeten gaan definieren als een DECIMAL ipv een FLOAT?

nu al op andere manier opgelost, maar zal eens kijken of dit invloed heeft op performance..

Through meditation I program my heart to beat breakbeats and hum basslines on exhalation -Blackalicious || *BetuweKees was AFK; op de fiets richting China en verder


  • Knutselsmurf
  • Registratie: December 2000
  • Laatst online: 15:23

Knutselsmurf

LED's make things better

Heeft niet zoveel met het oorspronkelijke probleem te maken, maar wel met de tijdenregistratie. Waarom sla je de tijden niet op als een integer? 100 is 1 seconde, 6000 1 minuut enzovoort. Dan heb je dat soort problemen als hierboven bechreven niet meer.

offtopic:
Is BetuweKees ook met Skits naar Collalbo geweest?

- This line is intentionally left blank -


  • BetuweKees
  • Registratie: Januari 2003
  • Laatst online: 15-05 20:44

BetuweKees

Flipje uit Tiel

Topicstarter
ok dan hier nog wat optimalisatie:
als ik INNER JOIN gebruik dat is me query ongeveer 33% langzamer merk ik; ik hou het dus lekker bij een LEFT JOIN..
daarnaast is die highscore query van jou (nadat database omgezet is van FLOAT(5,2) naar DECIMAL(5,2)) ongeveer 2 keer sneller dan de query die ik eerst had, nuttig dus.

(ofwel; als wij allebei onze eigen db zouden maken waren ze ongeveer even snel.. ;))

offtopic:
@Knutselsmurf: nee, ik was er niet; geef de voorkeur aan investeren in een skivakantie :)
Jij nog mee geweest? En hoe staat het er voor met jouw tijden database?

Through meditation I program my heart to beat breakbeats and hum basslines on exhalation -Blackalicious || *BetuweKees was AFK; op de fiets richting China en verder

Pagina: 1