The relevant tables and attempted solution have been listed at the bottom of this post. The goal and the problem are described immediately below.
The Goal
The goal of this query is to build the PHP array of objects (returned rows) below. This is a timestamped history of every transaction made for each currency pair filtered by user. I am able to achieve everything except for the cumulative_quantity
values
'BTC-USD' => array(
array(
'timestamp' => (int),
'price' => (float),
'price_usd' => (float),
'buy_sell' => (bool),
'quantity' => (float),
'total_value' => (float),
'total_value_usd' => (float),
'cumulative_quantity' => (float),
'cumulative_quantity_base' => (float)
)
)
The Problem
Calculating the cumulative quantity for each user's row in pf_items
requires also checking whether the buy_sell
field is 0 (sell) or 1 (buy) and adding/subtracting accordingly.
It is made slightly more complex as cumulative_quantity_base
requires that the quantity
values for BTC-USD and (for instance) BTC-EUR are merged under a simple BTC array of objects. For instance, if a row in pf_items
relating to BTC-USD (base_currency
and quote_currency
) had a buy quantity of 5, and another row relating to BTC-EUR had a buy quantity of 7, it would need to find the cumulative value for BTC of these two rows: 12.
pf_currencies
CREATE TABLE `pf_currencies` (
`id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`symbol` varchar(255) NOT NULL
);
pf_currencies_history
CREATE TABLE `pf_currencies_history` (
`id` int(11) NOT NULL,
`base_currency` int(11) NOT NULL,
`quote_currency` int(11) NOT NULL,
`price` float NOT NULL,
`date_time` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
);
pf_portfolios
CREATE TABLE `pf_portfolios` (
`id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`date_added` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
pf_items
CREATE TABLE `pf_items` (
`id` int(11),
`portfolio_id` int(11),
`action_date` date,
`price` float,
`price_usd` float,
`buy_sell` tinyint(1),
`quantity` float,
`base_currency` int(11),
`quote_currency` int(11),
`date_added` datetime
)
My Query
This query achieves what is needed except for cumulative_quantity
and cumulative_quantity_base
as described.
SELECT (SELECT
symbol
FROM pf_currencies
WHERE a.base_currency = id)
AS base_currency,
(SELECT
symbol
FROM pf_currencies
WHERE a.quote_currency = id)
AS quote_currency,
a.price,
UNIX_TIMESTAMP(a.date_time) AS unix_time
FROM pf_currencies_history a
INNER JOIN pf_items i
ON i.portfolio_id = (SELECT
id
FROM pf_portfolios
WHERE user_id = ".$userId.")
AND a.base_currency = i.base_currency
AND a.quote_currency = i.quote_currency
ORDER BY unix_time DESC