SQL to find the average amount of money spent by country? - sql

I need to find the average amount of money spent by country, using the two tables below in oracle. Sale_total is the money spent in each sale and Cust_country is the customer's country. Any help would be greatly appreciated.
Tables
Sale
Sale_Id
Payment_ID
Ship_Id
Customer_ID
Sale_total ==> Money Spent
Sale_date
Sale_time
Customer
Cust_name
Cust_address
Cust_city
Cust_country
Cust_phone
Cust_age
Cust_sex

You need to have a link between the Sale and Customer tables. Presumably place Customer_ID in the Customer table as a primary key, and have Customer_ID in the Sale table be a foreign key. Assuming you do that, you can then run the below query.
SELECT
AVG(S.Sale_Total) Spent,
c.Cust_country
FROM
Sale S
INNER JOIN
Customer C on S.Customer_ID=C.Customer_ID
GROUP BY C.Cust_Country
This tells you the average amount spent, and the country where it was spent.
The key to understanding this answer is that AVG (the average function) is an aggregate function, as it combines things. Often when you have an aggregate function, you have to group the other columns, hence why we included the GROUP BY clause.
The reason you need Customer Id in the Customer table (apart from being the logical place for it) is so that you can establish a relationship between the Customer and Sale tables.
Another way to establish the relation is you can create a new table to link Customer and Sale together. Call it Customer Sales. For example:
Customer_Sales
Customer_Id
Sale_Id
Then you'd adjust the query to join based on that.

Try this:
SELECT C.Cust_country as Country, AVG(S.Sale_total) as Spent
FROM Sale S INNER JOIN
Customer C on S.Customer_ID=C.Customer_ID
GROUP BY C.Cust_country
AVG is an aggregate function that evaluates the average of an expression over a set of rows.
Read more about here.

Related

SQL QUERY for sum loans per customer

enter image description here
I need a query that returns all customers whose name contains the string "Will", and their associated total loan values.
Loan totals should be sorted from largest amount to smallest amount and the loans totals column should be called "TotalLoanValue".
Only one record per customer should be returned.
SELECT name, loan_amount
FROM customers, loans
WHERE name LIKE '%WILL%'
I have wrote that query, but I'm having a hard time to figure out how to sum all the loan values per customer
To say first things first:
If you want to ask further questions here, you should please read and follow this: How to create a good example instead of just adding a link.
Otherwise, you will be on risk that your questions will just be closed and you will never get an answer.
To answer your question:
We need to JOIN the two tables by their common column and then build the SUM of all loan amounts with a GROUP BY clause of the customer name.
I didn't follow your link because I wouldn't know if this is spam, so let's say the customer table has a column "id" and the loan table a column "customer_id".
Then your query will look like this:
SELECT c.name, SUM(l.loan_amount)
FROM customers c
JOIN loan l
ON c.id = l.customer_id
WHERE c.name LIKE '%will%'
GROUP BY c.name
ORDER BY SUM(l.loan_amount) DESC, c.name;
The ORDER BY clause makes sure to begin with the customer having the highest sum of loan amounts.
The "c.name" at the end of the ORDER BY clause could be removed if we don't care about the order if different customers have the same sum of loan amounts.
Otherwise, if we use the query as shown, the result will be sorted by the sum of loan amounts first and then with a second priority by the customer name, i.e. will sort customers having the identic sum of loan amounts by their name.
Try out with some sample data here: db<>fiddle

Select results get multiplied on joining

I'm using an SQL Server database which has Order table contains a foreign key called invoice_id, this attribute belongs to Invoice table. Also, I have another table called "Receiptwhich also includesinvoice_idandamount_paid` attributes.
Many items can be assigned to the same invoice (customer may make many orders at once), also many receipts can be assigned to the same invoice (customer may make different payments to the same invoice as for example they can pay 50% and then pay the rest later).
So the problem I'm facing is when I try to select the total paid amounts from the Receipt table taking the order_id as a condition, the result will be multiplied according to the number of orders that have the same invoice_id
For example, customer A placed three orders at once, each order cost is 100 USD, which should be 300 USD in the invoice and he already paid that invoice. Now if I query the Receipt table for the paid amounts, the result will be 900 USD (300 USD * 3 orders), which is obviously incorrect.
I'm stuck at this issue, I believe there are some mistakes in my database logic, so please provide me your suggestions to solve this problem and also what should do with the database if the logic is incorrect.
Below is the query i'm using to get the result:
select sum(r.amount_paid), o.invoice_id from RECEIPT r, INVOICE i, ORDER o
where r.invoice_id = i.invoice_id
and o.invoice_id = i.invoice_id
group by o.invoice_id;
Here's three answers to three slightly different questions you might ask of your database.
Amount paid per invoice
If you are trying to get the total amount paid per invoice, all you need is
SELECT SUM(Amount_Paid) Total_Paid,
Invoice_ID
FROM Receipt
GROUP BY Invoice_ID
Amount paid per order
If you want to know the total paid per order, this is not quite possible in your data model as you have described it. If a invoice has three orders on it, and the invoice is only partly paid, there is no way to tell which of the the orders is paid and which is not.
You need some additional data structure that indicates how payments are applied to orders within an invoice, e.g. an Allocation or Split table.
Amount paid on invoices that pertain to one or more orders
On the other hand, if you want to know how much payment has been received on invoices that contain one or more order IDs, you could write this:
SELECT SUM(Amount_Paid) Total_Paid,
Invoice_ID
FROM Receipt
WHERE Invoice_ID IN (SELECT Invoice_ID
FROM Order
WHERE Order_ID IN (1,2,3,4)) --Edit these IDs for your specific case
GROUP BY Invoice_ID
Notice none of the queries above required any joins, so no multiplying :)
Please, try this:
SELECT SUM(r.amount_paid), r.invoice_id FROM RECEIPT r
JOIN INVOICE i ON r.invoice_id = i.invoice_id
JOIN ORDER o ON r.invoice_id = o.invoice_id AND r.order_id = o.order_Id
GROUP BY r.invoice_id;

Sql join only on the first match

I don't know how to perform the the following case.
I have the sales info in a table:
Number of Bill (key),
Internal number (key),
Client,
Date (month-year),
Product group,
Product,
Quantities,
Total,
Sales man.
I need to joint this sales tables with the annual forecast sales table that is the next one:
Date (key),
Group product(key),
Sales man (key),
Total.
In each tables the combination of the key is the primary key. I need to add in the sales tables the forecast. For this I need to add the sales of the forecast in the real sale only on the first match of date, group product and sales man, so the total of forecast sales don't get bigger than it is (a sales man can sell the same group product, to the same client, in the same day on multiple times).
.. only on the first match of date, group product and sales man ..
You can use window functions for this, consider using ROW_NUMBER() OVER(PARTITION BY ... ORDER BY ... ). First match has row number of 1.
More information and examples (sales!) can be found from MSDN.

GROUP BY clause with logical functions

I'm using Oracle 11g Application Express, and executing these commands within the SQL Plus CLI. This is for a class, and I cannot get past this problem. I don't know how to add the total quantity of the items on the orders - I get confused as I don't know how to take the SUM of the QUANTITY per ORDER (customers have multiple orders).
For each customer having an order, list the customer number, the number of orders
that customer has, the total quantity of items on those orders, and the total price for
the items. Order the output by customer number. (Hint: You must use a GROUP BY
clause in this query).
Tables (we will use):
CUSTOMER: contains customer_num
ORDERS: contains order_num, customer_num
ITEMS: contains order_num, quantity, total_price
My logic: I need to be able to calculate the sum of the quantity per order number per customer. I have sat here for over an hour and cannot figure it out.
So far this is what I can formulate..
SELECT customer_num, count(customer_num)
FROM orders
GROUP BY customer_num;
I don't understand how to GROUP BY very well (yes, I have googled and researched it for a bit, and it just isn't clicking), and I have no clue how to take the SUM of the QUANTITY per ORDER per CUSTOMER.
Not looking for someone to do my work for me, just some guidance - thanks!
select o.customer_num,
count(distinct o.order_num) as num_orders,
sum(i.quantity) as total_qty,
sum(i.total_price) as total_price
from orders o
join items i
on o.order_num = i.order_num
group by o.customer_num
order by o.customer_num
First thing:
you have to join the two tables necessary to solve the problem (orders and items). The related field appears to be order_num
Second thing:
Your group by clause is fine, you want one row per customer. But because of the join to the items table, you will have to count DISTINCT orders (because there may be a one to many relationship between orders and items). Otherwise an order with 2 different associated items would be counted twice.
Next, sum the quantity and total price, you can do this now because you've joined to the needed table.
This is also solved by using WHERE:
SELECT orders.customer_num, /*customer number*/
COUNT(DISTINCT orders.order_num) AS "num_orders", /*number of orders/c*/
SUM(items.quantity) as "total_qty", /*total quantity/c*/
SUM(items.total_price) as "total_price" /*total price/items*/
/* For each customer having an order, list the customer number,
the number of orders that customer has, the total quantity of items
on those orders, and the total price for the items.
Order the output by customer number.
(Hint: You must use a GROUP BY clause in this query). */
FROM orders, items
WHERE orders.order_num = items.order_num
GROUP BY orders.customer_num
ORDER BY orders.customer_num
;

Creating an SQL query to list all clients, who spent over 1000$

So, I have three tables with the following rows: Customers (Customer_id and Name), Orders (Customer_id, Product_id, Quantity) and Products (Price).
How do I write a query which shows all customers who spent more than 1000$? Do I have to join the tables?
Because this is homework, I'm not going to give you the answer, just information on how to arrive at the answer.
You need to include the customers table, because that's what your looking for, customers. You'll need to join in aggregate with the orders table, so you can find out how many of each product they've ordered, and you'll need to join with the products table to find the prices of all those items in order to total them up to determine if they've spent more than $1000.
Go to it. Tell us how you get on.
SELECT * FROM customer c JOIN (
SELECT a.customer_id,SUM(a.quantity*b.price) spent FROM orders a
JOIN products b ON b.product_id=a.product_id GROUP BY a.customer_id
) d ON d.customer_id=c.customer_id WHERE d.spent>1000