Here are the mysql table and data statements;
CREATE TABLE temp_sales (
order_number INT,
region varchar(20),
currency varchar(3),
sales_value decimal(13,2)
);
INSERT INTO temp_sales VALUES
(1, 'ASIA', 'JPY', 100.00),
(2, 'ASIA', 'JPY', 200.00),
(3, 'ASIA', 'JPY', 300.00),
(4, 'AMERICAS', 'USD', 100.00),
(5, 'AMERICAS', 'USD', 200.00),
(6, 'AMERICAS', 'USD', 300.00);
CREATE TABLE temp_exchange_rate (
currency varchar(3),
exchange_rate decimal(5,2)
);
INSERT INTO temp_exchange_rate VALUES
('JPY', 1.40),
('USD', 1.50);
To run this SQL;
SELECT ms.order_number
,ms.region
,ms.sales_value * er.exchange_rate AS base_value
,ms.order_rank
FROM temp_exchange_rate er
inner join
( SELECT s.order_number
,s.region
,s.currency
,s.sales_value
,@order_rank := if(@sale_currency = s.currency, @order_rank + 1, 1) AS order_rank
,@sale_currency := s.currency
from temp_sales AS s
order by s.region
,s.sales_value desc
) as ms on ms.currency = er.currency
WHERE 1 = 1
and ms.order_rank = 1;
The results from MySQL v5.7 are as follows;
| ms.order_number | ms.region | base_value | ms.order_rank |
|---|---|---|---|
| 3 | ASIA | 420.0000 | 1.0 |
| 6 | AMERICAS | 450.0000 | 1.0 |
If I put the same statement into node js and print out each record I get the following results ;
main #3 6
main #4 1 // ASIA // 140.0000 // 1
main #4 3 // ASIA // 420.0000 // 1
main #4 2 // ASIA // 280.0000 // 1
main #4 6 // AMERICAS // 450.0000 // 1
main #4 5 // AMERICAS // 300.0000 // 1
main #4 4 // AMERICAS // 150.0000 // 1
main #5
The issue appears to be the temporary variables
@order_rank & @sale_currency
which are NOT set correctly in nodejs
Here's the code ;
async function getSymbols4EOD(pool) {
let uiStmt = ` SELECT ms.order_number
,ms.region
,ms.sales_value * er.exchange_rate AS base_value
,ms.order_rank
FROM temp_exchange_rate er
inner join
( SELECT s.order_number
,s.region
,s.currency
,s.sales_value
,@order_rank := if(@sale_currency = s.currency, @order_rank + 1, 1) AS order_rank
,@sale_currency := s.currency
from temp_sales AS s
order by s.region
,s.sales_value desc
) as ms on ms.currency = er.currency
WHERE 1 = 1
and ms.order_rank = 1 `;
console.log('getSymbols4EOD START');
// START
const connection = await pool.getConnection();
console.log('getSymbols4EOD POST CONNECTION');
try {
console.log('getSymbols4EOD PRE-QUERY', uiStmt);
const results = await connection.query(uiStmt);
connection.release();
return results[0];
} catch (err) {
console.log('getSymbols4EOD ERR', err);
connection.release();
throw err; // not connected!
}
// END
}
async function main() {
const mysql = require('mysql2/promise');
const config = {
host: 'localhost',
user: 'blah',
password: 'blahvlah',
database: 'db-blah',
waitForConnections: true,
connectionLimit: 10,
queueLimit: 0
};
const pool = mysql.createPool(config);
console.log('main #1');
try {
console.log('main #2');
let indexRows = await getSymbols4EOD(pool);
console.log('main #3',indexRows.length);
for (const row of indexRows) {
console.log('main #4', row.order_number, '//', row.region, '//', row.base_value, '//', row.order_rank) ;
}
} catch (err) {
console.log('main #4a',err);
}
console.log('main #5');
pool.end();
}
main();
So first question;
- Am I doing anything wrong ?
- Is there a different SQL statement which will give me the desired results ?