[mySQL 3.23.37] SUM() levert niet de som van de kolom

Pagina: 1
Acties:

  • Hoppie
  • Registratie: Februari 2001
  • Niet online
Situatie
Ben bezig met een php script voor het bijhouden van het brandstofverbruik van m'n auto. Daarbij gebruik ik de volgende tabel:
code:
1
2
3
4
5
6
7
8
9
10
11
CREATE TABLE `tbl_FuelCost` (
  `iFuelCost_Id` int(11) NOT NULL auto_increment,
  `iFuelCost_Date` int(11) NOT NULL default '0',
  `iFuelCost_Mileage` int(11) NOT NULL default '0',
  `fFuelCost_AverageMileagePerDay` float NOT NULL default '0',
  `fFuelCost_LitersFuel` float NOT NULL default '0',
  `fFuelCost_FuelCost` float NOT NULL default '0',
  `fFuelCost_CostPerLiter` float NOT NULL default '0',
  `fFuelCost_FuelConsumptionPer100km` float NOT NULL default '0',
  PRIMARY KEY  (`iFuelCost_Id`)
) TYPE=MyISAM AUTO_INCREMENT=177 ;

Nu wil ik van de laatste x toevoegingen de som van de hoeveelheid getankte liters brandstof hebben.
Voorbeeldtabel: van de laatste vier toevoegingen wil ik de som hebben:
code:
1
2
3
4
5
6
7
8
9
"168";"1085011200";"126087";"604";"39.54";"32.38";"0.819";"6.55"
"169";"1086048000";"126852";"765";"44.89";"36.32";"0.809";"5.87"
"170";"1086825600";"127648";"796";"45.1";"35.4";"0.785";"5.67"
"171";"1087516800";"128441";"793";"44.36";"35";"0.789";"5.59"
"172";"1088121600";"129101";"660";"38.73";"30.95";"0.799";"5.87"
"173";"1088726400";"129850";"749";"41.13";"32.62";"0.793";"5.49"
"174";"1088812800";"130159";"309";"18.06";"14.36";"0.795";"5.84"
"175";"1088812800";"130665";"506";"26.11";"20.76";"0.795";"5.16"
"176";"1089331200";"131397";"732";"44.02";"35.79";"0.813";"6.01"

Het resultaat zou moeten zijn: 44.02 + 26.11 + 18.06 + 41.13 = 129.32 liter.
Ik maak gebruik van de volgende query om dit resultaat te krijgen:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
SELECT 
    SUM(fFuelCost_LitersFuel) as sumLitersFuel,
    iFuelCost_Date,
    fFuelCost_FuelCost
FROM 
    tbl_FuelCost
GROUP BY
    iFuelCost_date,
    fFuelCost_FuelCost
ORDER BY
    iFuelCost_date
DESC
LIMIT
    4

Het resultaat is echter niet dus niet wat ik verwacht. Ik verwacht dat sumLitersFuel de som van de vier gevonden resultaten bevat, maar ik krijg het volgende:
code:
1
2
3
4
5
6
7
8
+------------------+----------------+--------------------+
| sumLitersFuel    | iFuelCost_Date | fFuelCost_FuelCost |
+------------------+----------------+--------------------+
| 44.0200004577637 |     1089331200 |              35.79 |
| 18.0599994659424 |     1088812800 |              14.36 |
| 26.1100006103516 |     1088812800 |              20.76 |
| 41.1300010681152 |     1088726400 |              32.62 |
+------------------+----------------+--------------------+

wat heb ik zelf gedaan?
Een hoop geklooid met behulp van PHPmyAdmin en gezocht met Google.
http://dev.mysql.com/doc/mysql/en/SELECT.html
http://dev.mysql.com/doc/mysql/en/Unnamed_views.html
http://dev.mysql.com/doc/mysql/en/GROUP-BY-Functions.html
De laatste pagina vertelt het een en ander over de SUM functie, maar helaas niet in combinatie met LIMIT.
http://forums.devshed.com/showthread.php?t=161386
Toont het limiteren van de resultaten door het between statement, maar dat levert ook niet het gewenste resultaat.
de Vraag
Hoe kan ik het door mij gewenste resultaat bereiken?

offtopic:
Klein extra vraagje: wie kan me de afwijkende decimalen verklaren? Ik weet dat PHP de neiging heeft floats te vernaggelen, maar by mySQL ben ik me daarvan niet bewust.

  • Shadowman
  • Registratie: Januari 2002
  • Niet online
Een float kan ietwat afwijken van wat het exact is. Daardoor krijg je dit soort resultaten.

Een float in het algemeen dus. En niet alleen die van php :)

  • Hoppie
  • Registratie: Februari 2001
  • Niet online
Shadowman schreef op 13 juli 2004 @ 00:28:
Een float kan ietwat afwijken van wat het exact is. Daardoor krijg je dit soort resultaten.

Een float in het algemeen dus. En niet alleen die van php :)
Een double van maken dan? Of is dat slechts een andere benaming voor hetzelfde type?
check => levert hetzelfde resultaat op.
Welk type levert niet dit probleem op?

Ik gebruik maximaal 3 cijfers achter de komma. Misschien toch maar vermenigvuldigen met 1000 en casten als integer?

[ Voor 13% gewijzigd door Hoppie op 13-07-2004 07:58 ]


  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
je groepeert op de datum en de kosten. als de combinatie van datum en de kosten dus 4 verschillende combinaties opleveren, dan krijg je dus ook 4 rows terug. en aangezien dat net de 4 rows zijn die je selecteert wordt er dus in feite niets opgeteld.
groepeer maar eens alleen op de datum, dan zul je zien dat 174 en 175 wel bij elkaar worden opgeteld

  • Hoppie
  • Registratie: Februari 2001
  • Niet online
marty schreef op 13 juli 2004 @ 08:16:
groepeer maar eens alleen op de datum, dan zul je zien dat 174 en 175 wel bij elkaar worden opgeteld
Dan moet het deze query worden:
code:
1
2
3
4
5
6
7
8
9
10
11
12
SELECT 
    iFuelCost_Date, 
    SUM(dFuelCost_LitersFuel) AS sum_LitersFuel 
FROM 
    tbl_FuelCost 
GROUP BY 
    iFuelCost_Date 
ORDER BY 
    iFuelCost_Date 
DESC 
LIMIT 
    4

Maar dit levert het op:
code:
1
2
3
4
5
6
7
8
+----------------+------------------+
| iFuelCost_Date | sum_LitersFuel   |
+----------------+------------------+
|     1089331200 | 44.0200004577637 |
|     1088812800 | 44.1700000762939 |
|     1088726400 | 41.1300010681152 |
|     1088121600 | 38.7299995422363 |
+----------------+------------------+

Voor m'n gevoel doe ik alles zoals het zou moeten, maar vergeet ik een kleinigheidje. |:(
Zou het kunnen dat mySQL 3.23.37 dit niet kan?
Kan er een setting verkeerd staan?

Ik wil eenvoudigweg van de vier meest recente tankbeurten de hoeveelheid liters optellen. Dat zou toch moeten kunnen? :?

  • marty
  • Registratie: Augustus 2002
  • Laatst online: 27-03-2023
Hoppie schreef op 13 juli 2004 @ 19:50:
Ik wil eenvoudigweg van de vier meest recente tankbeurten de hoeveelheid liters optellen. Dat zou toch moeten kunnen? :?
Ah, maar dat is wat anders. Let even op wat je doet: Je groepeert op datum -> dus, je zegt: tel van alle overeenkomstige data de hoeveelheid aan kosten bij elkaar op, en wil vervolgens van die uitkomst (die over de hele tabel gaat) de laatste 4 hebben. Dat is precies wat mysql heeft gedaan. (174 en 175 zijn ook netjes bij elkaar opgeteld).


Als je de kosten van de laatste 4 records bij elkaar op wil tellen, dan wordt dat lastig in mysql omdat het nog geen subqueries kan (of je moet een hele recente (alfa?) versie hebben). Dus dan zou je eerst met een query moeten bepalen wat het id is van het 4-na laatste record en dan kun je zoiets doen:

MySQL:
1
2
3
SELECT SUM(fFuelCost_LitersFuel) AS Kosten
FROM tbl_FuelCost
WHERE iFuelCost_Id >= [4-na-laatste-id]


Maar misschien dat je het dmv een creative join ook zonder subqueries kan oplossen. Maar heb nu geen tijd om m'n hoofd daar over te breken. sorry :)

  • curry684
  • Registratie: Juni 2000
  • Laatst online: 12-05 22:23

curry684

left part of the evil twins

Hoppie schreef op 13 juli 2004 @ 07:57:
[...]

Een double van maken dan? Of is dat slechts een andere benaming voor hetzelfde type?
Een float is op x86 platforms 4 bytes groot, een double verbazend genoeg 8 bytes. Inhoudelijk is het hetzelfde floating point beestje en daarmee inaccuraat :)

Professionele website nodig?


  • Hoppie
  • Registratie: Februari 2001
  • Niet online
marty schreef op 14 juli 2004 @ 10:20:
[...]
Als je de kosten van de laatste 4 records bij elkaar op wil tellen, dan wordt dat lastig in mysql omdat het nog geen subqueries kan (of je moet een hele recente (alfa?) versie hebben).
Dus mySQL (3.23.37) kan het dus gewoon niet. Dat valt me tegen, het lijkt me zo logisch....

Dan maar naar plan B: de laatste vier posts ophalen en binnen PHP optellen.
Jammer.
curry684 schreef op 14 juli 2004 @ 10:24:
[...]

Een float is op x86 platforms 4 bytes groot, een double verbazend genoeg 8 bytes. Inhoudelijk is het hetzelfde floating point beestje en daarmee inaccuraat :)
OK duidelijk.
Maar waar komen dan die getallen achter komma opeens vandaan? Lijkt me logisch dat als die getallen niet gedefinieerd zijn (passen niet binnen de float/double), dat ze dan op nul worden gezet. Blijkbaar gebeurt dat dus niet.
Pagina: 1