complex math routines in mysql - mysql

I have a table in Mysql that has field code with a value = 'A' that represents the type of sale of a part. The sale price is displayed as Price. There is a Quantity field that I need to multiply by the Price. The query sum(quantity*price) where code='A' gives me what I want. I also have a code = 'T' that represents the tax of the sum of the transactions. I can get that easy enough by sum(price) where code='T'. I need to subtract the value of the 'T' (tax) value from the sum(quantity*price).
I can do this by looping through two separate queryies but I would like to combine into one query.

You just want conditional aggregation:
select (sum(case when value = 'A' then quantity * price else 0 end) -
sum(case when value = 'T' then price else 0 end)
) as netprice

Related

SQL - sum operations within case when statement

I need to aggregate some sessions by day, country etc. The table has a transaction amount for each session (in local currency) and a field with the exchange_rate to EUR for the time of the transaction. Like this:
amount | currency | exchange_rate | date | country
I ran sum(amount/exchange_rate), however, for roughly 0.5% of the rows the value for exchange_rate is 0 and therefore it throws the error "cannot divide by 0".
I tried to run it with case when:
sum(case when exchange_rate = 0 then sum(amount) else sum(amount/exchange_rate) end) as volume
But apparently nested sum's are not allowed. Does anybody have an idea as to how I can get the result the above should logically produce, but without nested sums in a case when statement?
Assuming that an exchange rate of 0 indicates that the amount is in EUR currency already, you can do:
sum(amount / case when exchange_rate = 0 then 1 else exchange_rate end)
I think you want:
sum(case when exchange_rate = 0 then amount else amount/exchange_rate end) as volume
Or for a bit less typing:
sum(amount / coalesce(nullif(exchange_rate, 0), 1)) as volume
Essentially you want to consider the exchange rate as 1 when it's zero. You can do:
sum(case when exchange_rate = 0
then amount
else amount/exchange_rate
end
) as volume

I want to display the bill amount for productId on the basis of particular date for'31-jan-2016' and '31-mar-2016'

I want to display the bill amount for productId on the basis of particular date for '31-jan-2016' and '31-mar-2016' but the query display the Same bill amount for both dates. Suggest a query.
My query
Select productId,
sum(billAmount)as'31jan',
sum(billAmount)as '31Mar'
from test
where billDate='31-jan-2016 '
and '31-mar-2016'
group by productId;
The phrase
where billDate='31-jan-2016 'and '31-mar-2016'
doesn't mean what you think it means. '31-mar-2016' isn't a comparison expression. You probably want
where (billDate='something' OR billDate='anotherthing')
But, also, your date formatting isn't following the SQL standard. You may want dates formattted as '2016-03-31' instead. That's a guess, because you did not mention the data type of your billDate column.
Finally, you probably need to study up on how to use GROUP BY and SUM expressions.
Conditional aggregation seems like one approach to take:
Select productId,
sum(case when billDate = '2016-01-31' then billAmount else 0 end) as amount_20160131,
sum(case when billDate = '2016-03-31' then billAmount else 0 end) as amount_20160331
from test
where billDate in ('2016-01-31', '2016-03-01')
group by productId;
Notes:
This uses ISO standard date formats, YYYY-MM-DD.
Only use single quotes for string and date constants, not for column aliases.
The use of the case inside the sum() solves your problem.

Sum of multiple rows using different cases

In my table for payment details of a shop.Here Payment is done by using credit,debit and by cash.This will represent in the table like a field "mode"
If mode=1 cash,mode=2 credit and mode=3 debit.
Now i take the daily fee details using this query
SELECT * FROM (`fee_data`) WHERE `paid_date` = '2015-20-11'
I want to get the sum of Paid amount in different modes
How can i do this..
You can try this:
SET #paid_date = '2015-01-19 00:00:00';
SELECT
SUM (CASE WHEN MODE = 1 THEN VALUE_PAYMENT ELSE 0 END) TOTAL_1,
SUM (CASE WHEN MODE = 2 THEN VALUE_PAYMENT ELSE 0 END) TOTAL_2,
SUM (CASE WHEN MODE = 3 THEN VALUE_PAYMENT ELSE 0 END) TOTAL_3
FROM (`fee_data`) WHERE `paid_date` = #paid_date;
Where value_payment is the column you store the amount paid.
You can use sum(if( in combination with grouping by date, something like this:
SELECT `paid_date`, sum(if(mode=1, `fee_data`, 0)) sumMode1,
sum(if(mode=2, `fee_data`, 0)) sumMode2,
sum(if(mode=2, `fee_data`, 0)) sumMode3
FROM (`fee_data`) group by `paid_date`
With that you will get per date one line, where you have 3 aggregated columns. For each mode you have one aggregated field. Is that what you are looking for?
Try this :
SELECT * FROM (`fee_data`) WHERE `paid_date` = '2015-20-11' AND ModeID=1
make changes in DB tables accordingly
SELECT *, SUM(paid_amount) as sum_amount FROM (fee_data) WHERE paid_date = '2015-20-11' GROUP BY mode
I think this should work

MySQL Sum positive and negative - calculate the exact total from money transactions

I have a database table full of transactions. The transactions contain negative numbers from people returning items. I would like to add up all the amount field while also subtracting the negative values of returns from the total. How can I do this and output it out?
Currently the best I can do is get:
SELECT SUM(amount)
FROM outputaddition
GROUP by SIGN(amount);
But this only puts positive and negative in the same column.
SELECT personId,SUM(CASE WHEN amount<0 THEN amount ELSE 0 END) as NegativeTotal,
SUM(CASE WHEN amount>=0 THEN amount ELSE 0 END) as PostiveTotal
FROM outputaddition
GROUP BY personID
If you want single column
SELECT personId,SUM(amount) as Total
FROM outputaddition
GROUP BY personID
try this,
SELECT SUM(amount) as ActualTotal
,Sum(Case When amount > 0 then amount else 0 end) totalOfPositiveOnly
FROM outputaddition
I'm afraid your answer is ambiguous; we're not sure exactly what you're asking.
Most simply, if "subtracting the negative values" means you just want to ignore the negative returns:
select sum(amount)
where amount > 0;

mysql date range issue with values equal to 0 within dates period

please help me with this issue:
I have the following query:
select SUM(price) from prices_adverts
where advert_id="15"
and room_type_id="3"
and (date >= "2013-09-20" AND date <"2013-09-23")
order by price
This searches to find and SUM price for the room for dates between "2013-09-20" AND "2013-09-23"
but for example if dates 2013-09-21 and 2013-09-22 have value 0 and 2013-09-20 has value 25.00 the query will return sum of 25.00 for the whole date range. When the specific date has value 0 this means the room is not available, but when even 1 day has value greater than 0 the query accept the room as available because it has total value greater than 0.. Please advise me how to change the query so if even 1 day within daterange to has value 0 the query to return total value 0 for the whole period.. I hope you to understand the nature of this issue, thanks
Try this:
IF(SUM(price = 0), 0, SUM(price))
And I assume you'd like to GROUP BY room_id.
Also I'd suggest changing those 0's in your database to NULLs. Because at some point you can possibly have 0 price, which is not equivalent to not available. You won't be able to distinguish them which is no good.
I guess you've missed GROUP BY Room_id. So it should be something like:
select room_id,
CASE WHEN MIN(price) = 0 THEN 0 ELSE SUM(price) END as priceSum
from prices_adverts
where advert_id="15"
and room_type_id="3"
and (date >= "2013-09-20" AND date <"2013-09-23")
GROUP BY room_id
ORDER BY priceSum