Reputation: 99
Im trying to get a total sum of all the columns that meet a condition. Here is my current setup
SELECT
COUNT(order_type = 'BUY') AS buy_fill,
COUNT(order_type = 'SELL') AS sell_fill,
SUM(btc_total) AS fill_sum
FROM fill_orders
WHERE coin_id = '$coin'
AND time_stamp >= DATE_SUB(NOW(), INTERVAL 55 SECOND)
This is what I have now and its counting how many types of buy and sell orders I have and is also giving me sum of all orders but I need to the break the sum of the orders into BUY orders and SELL orders.
Heres the code that I'm trying trying to make work. I've added (btc_total WHERE order_type = 'BUY') and SUM(btc_total WHERE order_type = 'SELL')
SELECT
COUNT(order_type = 'BUY') AS buy_fill,
COUNT(order_type = 'SELL') AS sell_fill,
SUM(btc_total) AS fill_sum,
SUM(btc_total WHERE order_type = 'BUY') AS buy_total
SUM(btc_total WHERE order_type = 'SELL') AS sell_total
FROM fill_orders
WHERE coin_id = '$coin'
AND time_stamp >= DATE_SUB(NOW(), INTERVAL 55 SECOND)
Upvotes: 0
Views: 4938
Reputation: 108400
Change this:
SUM(btc_total WHERE order_type = 'BUY') AS buy_total
to this:
SUM(IF(order_type='BUY',btc_total,NULL)) AS buy_total
The MySQL IF()
function evaluates the first argument as a boolean, if that's TRUE, it returns the second argument, else it returns the third argument.
The IF()
will be evaluated for each row, and the return from that expression will get totaled up by the SUM() aggregate.
or, use the more ANSI-standard equivalent to achieve the same result:
SUM(CASE WHEN order_type = 'BUY' THEN btc_total END) AS buy_total
This pattern is commonly referred to as "conditional aggregation".
For the "counts" we can replace COUNT
with SUM
, like this:
SUM(order_type = 'BUY') AS buy_fill
MySQL evaluates the equality comparison as a boolean, which returns 1, 0 or NULL, which are then totaled up by the SUM aggregate. (A COUNT of that would include zeros and ones, not just the ones.)
The above is equivalent to
SUM( CASE
WHEN order_type = 'BUY' THEN 1
WHEN order_type <> 'BUY' THEN 0
ELSE NULL
END
) AS buy_fill
If we want to use a COUNT
aggregate, we could do it like this:
COUNT(IF(order_type = 'Buy',1,NULL)) AS buy_fill
(We could use any non-null value in place of 1
, and get an equivalent result.)
Upvotes: 3
Reputation: 35583
"conditional aggregates" conventionally contain a case expression
SELECT
COUNT(CASE WHEN order_type = 'BUY' THEN order_type END) AS buy_fill
, COUNT(CASE WHEN order_type = 'SELL' THEN order_type END) AS sell_fill
, SUM(btc_total) AS fill_sum
, SUM(CASE WHEN order_type = 'BUY' THEN btc_total ELSE 0 END) AS buy_total
, SUM(CASE WHEN order_type = 'SELL' THEN btc_total ELSE 0 END) AS sell_total
FROM fill_orders
WHERE coin_id = '$coin'
AND time_stamp >= DATE_SUB(NOW(), INTERVAL 55 SECOND)
Upvotes: 1