Reputation: 23
I geather prices for products in different online store which are in United States (us), United Kingdom (uk) and etc. and hold it in one mysql TABLE (com) in local currency. For example, for United States price in US Dollar, for United Kingdom - in GB pound.
TABLE com
---------------------------------------------------------------------------------------
| AUTO_INC | COUNTER | ID | CONC | VOLUME | PRICE | SHOP | DATE_G | COUNTRY |
|----------|---------|------|-----------|--------|-------|-----------|--------|---------|
| 115124 | 76720 | 2399 | prod_name | 13 | 34.23 | store1.us | 3 | us |
| 115186 | 50952 | 2399 | prod_name | 13 | 36 | store2.us | 3 | us |
| 115187 | 45828 | 2399 | prod_name | 13 | 37.44 | store3.us | 3 | us |
| 116448 | 73419 | 2399 | prod_name | 11.6 | 48 | store4.us | 3 | us |
| 116449 | 73421 | 2399 | prod_name | 13 | 65.5 | store4.us | 3 | us |
| 133334 | 22154 | 2399 | prod_name | 13 | 36.95 | store5.us | 4 | us |
| 133386 | 31646 | 2399 | prod_name | 13 | 37.44 | store3.us | 4 | us |
| 134828 | 54667 | 2399 | prod_name | 11.6 | 48 | store4.us | 4 | us |
| 134929 | 54670 | 2399 | prod_name | 13 | 65.5 | store4.us | 4 | us |
| 133337 | 22155 | 2399 | prod_name | 13 | 26.95 | store1.uk | 4 | uk |
| 133387 | 31647 | 2399 | prod_name | 13 | 17.44 | store2.uk | 4 | uk |
| 134829 | 54668 | 2399 | prod_name | 11.6 | 30 | store3.uk | 4 | uk |
| 134830 | 54671 | 2399 | prod_name | 13 | 45.5 | store4.uk | 4 | uk |
---------------------------------------------------------------------------------------
To convert prices from local currencies to US dollar I have created TABLE my_currency
TABLE my_currency
--------------------------------------
| AUTO_INC | DOMAIN | EX_RATE | DATE_G |
|----------|--------|---------|--------|
| 235 | uk | 0.6066 | 4 |
| 236 | us | 1 | 4 |
| 237 | uk | 0.6066 | 3 |
| 238 | us | 1 | 3 |
--------------------------------------
If I want to select minimum prices for us online stores (where COUNTRY = 'us'), I use the following query:
SELECT t1.* FROM com as t1
INNER JOIN (
SELECT id, conc, volume, min(price) as usd_price, date_g
FROM com
WHERE id=2399 AND date_g=4 AND country='us'
GROUP BY conc, volume) as t2
ON t1.conc=t2.conc and t1.volume=t2.volume and t1.id=t2.id and t1.price=t2.usd_price and t1.date_g=t2.date_g
ORDER BY conc DESC, volume DESC
And I get CORRECT result:
| AUTO_INC | COUNTER | ID | CONC | VOLUME | PRICE | SHOP | DATE_G | COUNTRY |
|----------|---------|------|-----------|--------|-------|-----------|--------|---------|
| 133334 | 22154 | 2399 | prod_name | 13 | 36.95 | store5.us | 4 | us |
| 134828 | 54667 | 2399 | prod_name | 11.6 | 48 | store4.us | 4 | us |
But now my goal is to select minimum price from all stores (country in ('us', 'uk')) and take into account that database holds prices in local currencies: 1. convert prices from local currencies to us dollar 2. select minimum prices in us dollar
So I tried to use the following query:
SELECT t1.auto_inc, t1.id, t1.conc, t1.volume, (t1.price / my_currency.ex_rate) as sub_price, t1.date_g
FROM com as t1
inner join my_currency
ON t1.country=my_currency.domain AND t1.date_g=my_currency.date_g
inner join (
select com.id, com.conc, com.volume, min(com.price / my_currency.ex_rate) as usd_price, com.date_g
from com
inner join my_currency
ON com.country=my_currency.domain AND com.date_g=my_currency.date_g
WHERE com.id=2399 AND com.date_g=4 AND com.country in ('us', 'uk')
GROUP BY conc, volume) as t2
on
t1.id=t2.id and
t1.conc=t2.conc and
t1.volume=t2.volume and
(t1.price / my_currency.ex_rate)=t2.usd_price and
t1.date_g=t2.date_g
ORDER BY conc DESC, volume DESC
But I get INCORRECT result:
| AUTO_INC | ID | CONC | VOLUME | SUB_PRICE | DATE_G |
|----------|------|-----------|--------|-----------|--------|
| 134828 | 2399 | prod_name | 11.6 | 48 | 4 |
CORRECT result is:
| AUTO_INC | ID | CONC | VOLUME | SUB_PRICE | DATE_G |
|----------|------|-----------|--------|-----------|--------|
| 134828 | 2399 | prod_name | 11.6 | 48 | 4 |
|----------|------|-----------|--------|-----------|--------|
| 133387 | 2399 | prod_name | 13 | 28.750412 | 4 |
Does anybody have any ideas? sqlfiddle.com
Upvotes: 2
Views: 100
Reputation: 1270311
The problem is the join
on the calculated decimal value. The following works:
SELECT t1.auto_inc, t1.id, t1.conc, t1.volume,
(t1.price / my_currency.ex_rate) as sub_price, t1.date_g
FROM com as t1 inner join
my_currency
ON t1.country = my_currency.domain AND t1.date_g = my_currency.date_g
inner join
(select com.id, com.conc, com.volume, min(com.price / my_currency.ex_rate) as usd_price, com.date_g
from com inner join
my_currency
ON com.country = my_currency.domain AND
com.date_g = my_currency.date_g
WHERE com.id=2399 AND com.date_g = 4 AND
com.country in ('us', 'uk')
GROUP BY com.id, com.conc, com.volume
) as t2
on t1.id = t2.id and
t1.conc = t2.conc and
t1.volume = t2.volume and
abs((t1.price / my_currency.ex_rate) - t2.usd_price) < 0.01 and
t1.date_g = t2.date_g
ORDER BY conc DESC, volume DESC;
However, if you change the join
condition on price
to:
t1.price / my_currency.ex_rate = t2.usd_price and
Then it doesn't work.
It does work if you cast both results back to decimal(10, 2)
:
cast(t1.price / my_currency.ex_rate as decimal(10, 2)) = cast(t2.usd_price as decimal(10, 2))
It might have something to do with this note in the documentation:
In division performed with /, the scale of the result when using two exact-value operands is the scale of the first operand plus the value of the div_precision_increment system variable (which is 4 by default). For example, the result of the expression 5.05 / 0.014 has a scale of six decimal places (360.714286)
Upvotes: 1