Operating Arithmetic Operations in SQL SELECT - mysql

I'm stuck on this problem :
Hello everybody (don't know why it does not appear on the first line...)
I have 2 tables :
-factures (invoices)
-commandes_clients (orders)
Each table contain unique id_client.
I'm trying to get and sort the average amount order of each client based on invoices amount : (total amount invoice for each client / number of orders of the same client)
Client 1 Average order amount 1254.21
Client 2 Average order amount 951.88
Client 3 Average order amount 891.11
...
I would like to sort by the average amount to get the client palmares
Table facture contains :
id_client, invoice_number, total amount
Table commandes_clients contains :
id_client
Thanks for your help

SELECT id_client,sum(total_amount)/count(invoice_number) as avg
FROM factures group by id_client order by avg;
Or:
SELECT id_client,sum(total_amount)/count(CC.id) as avg
FROM factures FA
INNER JOIN commandes_clients CC ON FA.id_client=CC.id_client
group by FA.id_client order by avg;
Try above query.

Related

How to solve this MySQL COUNT query?

Three table are given:
customer(cust_id, name, address, sales_id)
orders(order_id, cust_id,date, sales_id)
salesman(sales_id,commision)
and you have to write an MySQL query to "count the salesman by their order_id and date". Is the question is correct? if yes, how can I solve this.
The question is not clear, but the codes below will give you an idea of how to get aggregated results and you can play around / adjust based on your needs
select
date,
sales_id,
count(order_id) as total_orders_per_date_and_sales_id
from orders
group by 1,2
if you need the total salesman per date then you can do this:
select
date,
count(sales_id) as total_sales_man_per_date
from orders
group by 1
if one order has multiple sales owners, then you can find total salesman per order id
select
orders_id,
count(salesman) as total_sales_man_involved_per_order
from orders
group by 1
if you need total commission per salesman per date:
select
orders.date,
orders.sales_id,
sum(salesman.comission) as total_comssion_per_salesman_per_date
from orders
left join salesman
on orders.sales_id = salesman.sales_id
group by 1,2
total number of distinct salesman
select
count(distinct sales_id) as total_unique_salesman
from salesman

SQL how to find the average users from each category on a typical date

I have a user table as below;
Column Name Column Datatype Column Description
user_id varchar Unique user id
reg_ts timestamp Registration date
reg_device varchar Device registered
reg_attribution varchar Acquisition type
I am trying to find "On a typical day, what share of registrants are coming from each acquisition
source?"
I wrote the code below but not sure how to divide by the total number of records:
select reg_ts as registiration_date,
reg_attribution as acquisition_type,
count(*)
from users
group by 1,2
order by 1 asc
After I run the code above, I get only get the count of each acquisition type for each date. But I need to find the share of registrants are coming from each acquisition type. Can you please help me fix my query?
You can use a correlated subquery that gets the count for a day (assuming that reg_ts is a day despite being a timestamp).
SELECT u1.reg_ts AS registiration_date,
u1.reg_attribution AS acquisition_type,
count(*) / (SELECT count(*)
FROM users u2
WHERE u2.reg_ts = u1.reg_ts) AS share
FROM users u1
GROUP BY u1.reg_ts,
u1.reg_attribution
ORDER BY u1.reg_ts ASC;
Edit:
If you want the ratio in regard to the total number of users rather than users that registered that day just remove the WHERE clause from the subquery.
SELECT u1.reg_ts AS registiration_date,
u1.reg_attribution AS acquisition_type,
count(*) / (SELECT count(*)
FROM users u2) AS share
FROM users u1
GROUP BY u1.reg_ts,
u1.reg_attribution
ORDER BY u1.reg_ts ASC;
Use window functions:
select reg_ts as registiration_date,
reg_attribution as acquisition_type,
count(*) / sum(count(*)) over () as ratio
from users
group by 1, 2
order by 1 asc;
These have been available in MySQL version 8.0.

MYSQL - SUM of a column based on common value in other column

I'm stuck on crafting a MySQL query to solve a problem. I'm trying to iterate through a list of "sales" where I'm trying to sort the Customer IDs listed by their total accumulated spend.
|Customer ID| Purchase price|
10 |1000
10 |1010
20 |2111
42 |9954
10 |9871
42 |6121
How would I iterate through the table where I sum up purchase price where the customer ID is the same?
Expecting a result like:
Customer ID|Purchase Total
10 |11881
20 |2111
42 |16075
I got to: select Customer ID, sum(PurchasePrice) as PurchaseTotal from sales where CustomerID=(select distinct(CustomerID) from sales) order by PurchaseTotal asc;
But it's not working because it doesn't iterate through the CustomerIDs, it just wants the single result value...
You need to GROUP BY your customer id:
SELECT CustomerID, SUM(PurchasePrice) AS PurchaseTotal
FROM sales
GROUP BY CustomerID;
Select CustomerID, sum(PurchasePrice) as PurchaseTotal FROM sales GROUP BY CustomerID ORDER BY PurchaseTotal ASC;
Just by having a little Google search, I managed to find a page doing exactly what you're doing (I think). I have tailored the query below to fit your circumstance.
SELECT CustomerID, SUM(PurchasePrice) AS PurchaseTotal
FROM sales
GROUP BY CustomerID
ORDER BY PurchaseTotal ASC
Link to Page with Tutorial on SQL Groups

In Left join with order by always fetch first data from relational table. (Rails)

I have two tables like invoices and receipts
1. invoices
id name amt status
1 test 100 paid
2 test1 300 not paid
3 test2 400 not paid
2. receipts
id amount invoice_id receipt_date
1 50 1 22-apr-2014
2 30 1 24-apr-2014
3 30 1 25-apr-2014
Following is my query
#invoices_info = Invoice.select("invoices.id as inv_id,receipts.receipt_date as receipt_date,sum(receipts.amount) as receipt_amount")
.joins('left join receipts on receipts.invoice_id = invoices.id')
.where("invoices.status in ('Paid')")
.group("invoices.id").order("receipts.receipt_date desc")
This query shows data as:
inv_id receipt_amount receipt_date
1 100 22-apr-2014
So problem is, it fetch first date rather than descending date. I want last receipt date "25-apr-2014".
Can anyone help me?
Your Invoice.select() doesn't map to valid SQL. Valid SQL requires every unaggregated column in the SELECT clause to also appear in the GROUP BY clause. MySQL's "extension" to GROUP BY, which allows what you did, is not deterministic. (MySQL is giving you whatever date is easiest for it to fetch.) SQL developers regard this as a bug, not a feature.
I'll use SQL for the rest of this answer.
Executing this SQL statement in PostgreSQL . . .
select invoices.id as inv_id, receipts.receipt_date as receipt_date, sum(receipts.amount) as receipt_amount
from invoices
left join receipts on receipts.invoice_id = invoices.id
where invoices.status in ('paid')
group by invoices.id, receipts.receipt_date
order by receipts.receipt_date desc
returns this output.
1 2014-04-24 30
1 2014-04-22 80
If you want only the sum per invoice, which makes more sense, you can use a much simpler SQL query.
select invoice_id, sum(amount)
from receipts
group by invoice_id;
1 110
If you want the sum and the date of the latest receipt . . .
select invoice_id, max(receipt_date), sum(amount)
from receipts
group by invoice_id;
1 2014-04-24 110

MySQL - Calculating Net Dues against two tables

Thanks in advance for any assistance. I am new to SQL and have looked at several related threads on this site, and numerous other sites on Google, but have not been able to figure out what I am doing wrong. I have looked at sub-selects, various JOIN options, and keeping bumping into the wrong solution/result.
I have two tables that I am trying to do a query on.
Table:Doctors
idDoctors
PracticeID
FirstName
LastName
Table: Vendor Sales
Id
ProductSales
SalesCommission
DoctorFirstName
DoctorLastName
Here is the Query I am struggling with:
SELECT t1.PracticeID
, SUM( t2.ProductSales ) AS Total_Sales
, COUNT( t1.LastName ) AS Doctor_Count
, COUNT( t1.LastName ) *150 AS Dues
, SUM( t2.ProductSales * t2.SalesCommission ) AS Credit
FROM Doctors AS t1
JOIN VendorSales AS t2 ON t1.Lastname = t2.DoctorLastName
GROUP BY t1.PracticeID
LIMIT 0 , 30
The objective of the Query is to calculate net dues owed by a Practice. I am not yet attempting to calculate the net amount, just trying to get the initial calculations correct.
Result (limited to one result for this example)
PracticeID Total_Sales Doctor_Count Dues Credit
Practice A 16583.04 4 600 304.07360
This is what the result should be:
PracticeID Total_Sales Doctor_Count Dues Credit
Practice A 16583.04 3 450 304.07360
The problem is that Total Sales sums the aggregate sales transactions (in this case 4 sales entries totaling 16584.04). Each of the 4 sales has an associated commission rate. The Credit amount is the total (sum) of the commission.
The sales and credit numbers are accurate. But the Doctor count should be 3 (number of Doctors in the practice). Dues should be $450 (150x3). But as you can see it is multiplying by 4 instead of 3.
What do I need to change in the query to get the proper calculations (Doctors and dues multiplied by 3 instead of 4? Or should I be doing this differently? Thanks again.
There are various odd things about your schema, and you have not provided the sample data to justify your asserted values.
The first oddity is that you have both first and last name for the doctor in the Doctors table, and in the Vendor Sales table - yet you join only on the last name. Next, you have an ID column, it seems, in the Doctors table, yet you do not use that in the Vendor Sales table for the joining column.
It is not clear whether there is one entry in the Vendor Sales table per doctor, or whether there can be several. Given the counting issues you describe, we must assume there can be several entries per doctor in the Vendor Sales table. It also isn't clear where the vendor is identified, but we have to assume that is not germane to the problem.
So, one set of data you need is the number of doctors per practice, and the dues (which is 150 currency units per doctor). Let's deal with that first:
SELECT PracticeID, COUNT(*) AS NumDoctors, COUNT(*) * 150 AS Dues
FROM Doctors
GROUP BY PracticeID
Then we need the total sales per practice, and the credit too:
SELECT t1.PracticeID, SUM(t2.ProductSales) AS Total_Sales,
SUM(t2.ProductSales * t2.SalesCommission) AS Credit
FROM Doctors AS t1
JOIN VendorSales AS t2 ON t1.Lastname = t2.DoctorLastName
GROUP BY t1.PracticeID
These two partial answers need to be joined on the PracticeID to produce your final result:
SELECT r1.PracticeID, r1.NumDoctors, r1.Dues,
r2.Total_Sales, r2. Credit
FROM (SELECT PracticeID, COUNT(*) AS NumDoctors, COUNT(*) * 150 AS Dues
FROM Doctors
GROUP BY PracticeID) AS r1
JOIN (SELECT t1.PracticeID, SUM(t2.ProductSales) AS Total_Sales,
SUM(t2.ProductSales * t2.SalesCommission) AS Credit
FROM Doctors AS t1
JOIN VendorSales AS t2 ON t1.Lastname = t2.DoctorLastName
GROUP BY t1.PracticeID) AS r2
ON r1.PracticeID = r2.PracticeID;
That should get you the result you seek, I believe. But it is untested SQL - not least because you didn't give us appropriate sample data to work with.