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
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;
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;
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'
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.
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