MySql - Pulling two different sums from the same column - mysql

I am working on a game with a MySql database. In the game we have a system where characters have a debt that can be paid. We track each debt singularly and flag whether its paid or not with a Boolean 0,1.
I am trying to understand how in a single query I can sum the total paid amount as well as the total owed amount from a single character ID. The tables are
charid, amount, paid (the boolean)
Currently if I just want to find out how much they owe I simply place
SELECT sum(amount) FROM debts WHERE paid='0';
So how would I modify this to create a resulting column for both paid='0' and paid='1' ?
Thanks all.

Use conditional aggregation. Since the paid flag holds 0/1 values, you can just do:
select
sum(paid * amount) amount_paid,
sum( (1 - paid) * amount) amount_owed
from debts

you can use conditional aggregation using select case.
SELECT
sum(case when paid = 0 then amount else 0 end) as not_paid
,sum(case when paid > 0 then amount else 0 end) as paid
FROM debts

SELECT user, paid, SUM(amount) total FROM debts GROUP BY user, paid

Related

Trying to query for email addresses with 'Open' status within Q1 and has annual value of specific amount

I have two tables, Accounts and Opportunities. Accounts table has columns account_name, account_id, and account_email_addresses. Opportunities has opp_id, account_id, opp_stage, created_date, close_date, and mrr (mrr=monthly recurring revenue)
I am wanting to query for a list of the account email addresses in 'Open' status (opp_stage), worth more than $10,000 in ANNUAL recurring revenue (I am thinking WHERE 'mrr' * 12 >= 10,000), and then lastly is within Q1 (I am thinking WHERE close_date BETWEEN '1/1/2023' AND '3/31/2023'
Can you critique my syntax and let me know if I have done anything wrong? I am particularly unsure about the WHERE NOT (the opp stage can be anything other than Closed Won or Closed Lost) and the MRR statements.
Select account_email_address, account_id
FROM Accounts
Right Join Opportunities
ON accounts.account_id=opportunities.account_id
WHERE NOT opp_stage 'Closed Won' OR 'Closed Lost'
AND close_date BETWEEN '1/1/2023' AND '3/31/2023'
AND 'mrr' * 12 >= 10,000;
The 'not' predicate operations have parser execution precedence. In your version of the condition, what you expect to see will not work. You need to write like this:
Select account_email_address, account_id
FROM Accounts
left Join Opportunities
ON accounts.account_id=opportunities.account_id
WHERE (opp_stage NOT in ('Closed Won','Closed Lost'))
AND close_date BETWEEN '1/1/2023' AND '3/31/2023'
AND 'mrr' * 12 >= 10,000;

How to find the aggregate total sum of debit - sum of credit and group in MYSQL?

I have a SQL Table with the following rows. I am trying to find the aggregate sum of each book_name with the formula, (sum of debit- sum of credit).
Thus this is the table,
book_name transaction_type amount
demo credit 20
demo debit 100
testing credit 10
testing debit 30
This is the result I want.
demo -80
testing -20
How do I do this query in MySQL? I have been trying various syntaxes and solutions but none seem to work.
One method is to use conditional aggregation:
select book_name, sum(case when transaction_type = 'credit' then amount else - amount end)
from t
where transaction_type in ('credit', 'debit')
group by book_name;

Formula expanded field and rounding cannot figure out

I have the following formula to put into mySQL
SELECT Order_Number,
Order_Date,
Product,
Quantity,
Price,
Commission,
Employee_Sold,
(Quantity*Price)*(Commission*.01) AS Commision_Paid
FROM Orders
WHERE Order_Date BETWEEN '2017-12-01' AND '2017-12-31'
The commission paid amount comes out with 2.992500 as one example.....
The commission field is setup as decimal(5,2).
In the expanded field (Commission_Paid) it would be nice for it to show up as 2.99 in this case.
I have tried the ROUND function in many places but I am not sure as I keep getting error messages.
Thanks in advance. Student here and deadline on my paper. Appreciated.
MySQL 5.5X running.
Use Round(x, 2)
SELECT Order_Number,
Order_Date,
Product,
Quantity,
Price,
Commission,
Employee_Sold,
round((Quantity*Price)*(Commission*.01), 2) AS Commision_Paid
FROM Orders
WHERE Order_Date BETWEEN '2017-12-01' AND '2017-12-31'

Selecting from the same table twice with results on the same line

I want to generate a monthly report of total payments received from clients and total sent to suppliers in a single mySQL query that return these two totals on the same line. I can do it with UNION but that returns the results on different rows. All payments are in a payments table with the basic structure:
id | id_order | id_contact | amount | date_time
Update:
contact_id can be either client or supplier. The related contacts table has a field contact_typewhich is either "SUP" or "CLI".
I would like the result to sum up all the payments received from clients and sent to suppliers during a time frame so I can generate the profit based on actual payments not the theoretical profit based on order sale price - my cost, especially because these orders are paid in installments over a long period of time so showing $5000 profit in June for an order placed in June is not relevant as long as the order is being paid 3000 in August and another 2000 in December.
Month | total $ sent to suppliers | total $ received from clients
June 2014 3000 5000
July 2014 2500 3800
Other supporting tables that I have are the "orders" table, the "contacts" table. Is there a way to do this with joins? Is this possible and OK performance wise and if not what other options do I have? (I am using MySQL 5.5 and will do this in PHP, if it matters)
You would use conditional aggregation. You don't provide key information, such as how you know whether someone is a supplier or client. The following is a sketch of what the query would look like:
select date_format(date_time, '%M %Y') as month,
sum(case when contact_id = "supplier" then amount else 0 end) as sent,
sum(case when contact_id = "client" then amount else 0 end) as received
from table t
group by date_format(date_time, '%M %Y')
order by min(date_time);
Note the order by. Because you are using a non-standard date format, this will still ensure that the rows are in temporal order.
This is the solution I came up with, based on #Gordon Linoff answer
select date_format(p.pay_dcreated, '%M %Y') as month,
sum(case when c.type_con = "FAC" then p.pay_amount else 0 end) as sent,
sum(case when c.type_con = "CST" then p.pay_amount else 0 end) as received
from payments_pay as p, contacts_con as c
where p.pay_idcon=c.id_con
group by date_format(p.pay_dcreated, '%M %Y')
order by min(p.pay_dcreated);
This gives me a result I wanted.

Mysql select query, splitting column data conditionally into 2 new columns

I have a table called credit_log and the columns are
user_id | amount
The amount can be positive or negative. Positive means credits bought, negative means credits spent.
So, I want to have a query which returns
user_id | Bought | Spent
essentially , i want to sum up positive amount values in to Bought and sum up negative amount in to Spent and I want to group by the user_id
Currently I have a query like this
select user_id,sum(amount) from credit_log group by user_id;
but it sums up both positive and negative values. How can I write a query to separate them?
Some conditional statements inside the query should work nicely:
SELECT
user_id,
SUM(IF(amount > 0, amount, 0)) bought,
SUM(IF(amount < 0, amount, 0)) spent
FROM credit_log
GROUP BY user_id;
select user_id, sum(if(amount>0,amount,0)) bought, sum(if(amount<0,amount,0)) spent
from web_user_credits group by user_id;
I'm not 100% the syntax is the same in mysql... but it looks like it:
select
user_id
,case when amount > 0 then amount else 0 end as bought
,case when amount < 0 then amount else 0 end as spent
from
credit_log
And you can go on to simply place sum() around the case statements (include the end but not as).
check this :
select user_id , sum(if(amount< 0 ,0 ,amount )) as spent,
sum(if(amount> 0 ,0 ,amount )) as bought
from credit_log group by user_id