[MySQL] Greater than is niet echt greater than

Pagina: 1
Acties:

  • Amras
  • Registratie: Januari 2003
  • Laatst online: 01-10-2025
Ik ben momenteel bezig met het verbeteren van m'n databases practicum en loop tegen een vaag probleem op. De volgende opgave werd fout bevonden:
Geef het aantal klanten dat bij aankopen in de maand juli van 2002 meer dan 10 % van het bedrag hadden aanbetaald.
Hierbij had ik de volgende query verzonnen:
SQL:
1
2
3
4
5
6
SELECT COUNT(*) 
FROM klant, verkoop 
WHERE klant.klant = verkoop.klant 
AND MONTH(datum) = 7 
AND YEAR(datum) = 2002 
AND aanbet > bedrag / 10;

Zeker niet een van de moeilijkste queries die ertussen zat en ik vroeg me af wat hier nu fout aan kon zijn. Ik dus geprobeerd uit te zoeken waar het fout gaat en dat blijkt de greater than (>) vergelijking in de laatste regel. Ik heb de bovenstaande query iets aangepast en gekeken naar het resultaat:
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
+-------+--------+---------+-------------+
| klant | aanbet | bedrag  | bedrag / 10 |
+-------+--------+---------+-------------+
|    18 | 299.85 | 1999.00 |    199.9000 |
|    23 | 202.39 | 1349.25 |    134.9250 |
|    86 | 224.85 | 1499.00 |    149.9000 |
|   126 |  14.37 |  143.70 |     14.3700 |
|   132 | 224.25 | 1495.00 |    149.5000 |
|   194 | 166.80 | 1112.00 |    111.2000 |
|   208 | 448.50 | 2990.00 |    299.0000 |
|   278 | 359.85 | 2399.00 |    239.9000 |
|   317 | 209.85 | 1399.00 |    139.9000 |
|   322 | 672.75 | 4485.00 |    448.5000 |
|   345 | 269.85 | 1799.00 |    179.9000 |
|   370 |  14.37 |  143.70 |     14.3700 |
|   420 |  11.95 |  119.50 |     11.9500 |
|   424 |  12.45 |  124.50 |     12.4500 |
|   479 | 314.70 | 2098.00 |    209.8000 |
|   480 | 336.15 | 2241.00 |    224.1000 |
|   505 | 209.85 | 1399.00 |    139.9000 |
|   513 | 224.25 | 1495.00 |    149.5000 |
|   515 | 209.85 | 1399.00 |    139.9000 |
|   569 | 269.10 | 1794.00 |    179.4000 |
|   583 | 209.85 | 1399.00 |    139.9000 |
|   642 | 314.70 | 2098.00 |    209.8000 |
+-------+--------+---------+-------------+
22 rows in set (0.01 sec)

Tot mijn verbazing worden er records gekozen waarbij aanbet toch echt exact gelijk is aan bedrag / 10. Voor de zekerheid geprobeerd met haakjes om bedrag / 10, zelfde resultaat. Ik heb ook nog geprobeerd om het getal eerst af te ronden naar 2 decimalen, maar dat had ook geen effect (logisch natuurlijk, maar je moet wat proberen).

M'n MySQL versie blijkt niet helemaal gek te zijn, want als ik de vergelijkingen als volgt test geeft hij wel het goede antwoord terug:
code:
1
2
3
4
5
6
7
mysql> SELECT 14.37 > 14.3700;
+-----------------+
| 14.37 > 14.3700 |
+-----------------+
|               0 |
+-----------------+
1 row in set (0.00 sec)

Ik heb gezocht met google en hier op GoT, maar beiden leverden geen resultaat. Ik heb ook de MySQL Reference Manual erop nageslagen, maar die is het met mij eens dat die waarden er toch echt niet tussen zouden mogen zitten.

Volgens mij is de oplossing vrij eenvoudig, maar ik kan hem echt niet vinden. Heeft iemand een idee?

  • sjroorda
  • Registratie: December 2001
  • Laatst online: 10:33
Misschien problemen met floating point afrondingen? Probeer het eens andersom:

aanbet > bedrag / 10

wijzigen in

aanbet * 10 > bedrag

Probeer het anders eens met haakjes om de (bedrag / 10) heen?

  • Amras
  • Registratie: Januari 2003
  • Laatst online: 01-10-2025
sjroorda schreef op woensdag 10 augustus 2005 @ 11:04:
Misschien problemen met floating point afrondingen? Probeer het eens andersom:

aanbet > bedrag / 10

wijzigen in

aanbet * 10 > bedrag

Probeer het anders eens met haakjes om de (bedrag / 10) heen?
Je eerste optie heb ik geprobeerd en dat heeft geen effect:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
mysql> SELECT klant.klant, aanbet, bedrag, aanbet * 10
    -> FROM klant, verkoop
    -> WHERE klant.klant = verkoop.klant
    -> AND MONTH(datum) = 7
    -> AND YEAR(datum) = 2002
    -> AND aanbet * 10 > bedrag;
+-------+--------+---------+-------------+
| klant | aanbet | bedrag  | aanbet * 10 |
+-------+--------+---------+-------------+
|    18 | 299.85 | 1999.00 |     2998.50 |
|    23 | 202.39 | 1349.25 |     2023.90 |
|    86 | 224.85 | 1499.00 |     2248.50 |
|   126 |  14.37 |  143.70 |      143.70 |
....

Je tweede optie, haakjes toevoegen, had ik al geprobeerd en heeft ook geen effect.

  • Vesta
  • Registratie: November 2004
  • Niet online

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

Wellicht helpt het om de getallen expliciet te truncaten?
TRUNCATE(X,D)

Returns the number X, truncated to D decimals. If D is 0, the result has no decimal point or fractional part. D can be negative to truncate (make zero) D digits left of the decimal point of the value X.
Of op te slaan als number ipv float/double. Hoewel ik niet weet hoe MySQL daar mee rekent, waarschijnlijk maakt ie er alsnog floats van.

[edit]
De tip van Vesta zal wel beter werken.

[ Voor 5% gewijzigd door ACM op 10-08-2005 11:32 ]


  • Amras
  • Registratie: Januari 2003
  • Laatst online: 01-10-2025
Met behulp van Vesta's tip heb ik het op kunnen lossen. Deze twee queries geven het goede resultaat:
SQL:
1
2
3
4
5
6
SELECT COUNT(*)
FROM klant, verkoop 
WHERE klant.klant = verkoop.klant 
AND MONTH(datum) = 7 
AND YEAR(datum) = 2002 
AND (aanbet - bedrag / 10) >= 0.001;

en
SQL:
1
2
3
4
5
6
SELECT COUNT(*)
FROM klant, verkoop 
WHERE klant.klant = verkoop.klant 
AND MONTH(datum) = 7 
AND YEAR(datum) = 2002 
AND FORMAT(aanbet, 2) > FORMAT(bedrag / 10, 2);


De eerste is sneller, dus die heb ik gekozen. Bedankt voor de hulp allemaal. :)
Pagina: 1