Count between multiple tables - sql

I have these 3 tables with the following structures:
Products
product_id | category_id | product_name
Customers
customer_id | customer_name
Orders
order_id | customer_id | product_id
I need to write a SQL query that will print the top customers regarding the number of categories they have bought products from (the best customer is the one that has bought from the most categories).
Can anyone show me how to do that?
I tried like this, but I get the following error "not a GROUP BY expression":
select
(select customer_name
from customers
where customers.customer_id = orders.customer_id) as name,
(select count(category_id)
from products
where products.product_id = orders.product_id)
from
orders
group by
customer_id
order by
count(customer_id) desc;
I managed to make the top regarding how many products the customers bought. The solution I used is:
select
(select customer_name from customers
where customers.customer_id = orders.customer_id) as name,
count(product_id) as "number of ordered products"
from
orders
group by
customer_id
order by
count(product_id) desc;

Nested queries for this? Sheesh...
Just join them already.
And then order by the unique categories
SELECT c.customer_name
, COUNT(DISTINCT p.category_id) AS TotalOrderedCategories
FROM Orders o
LEFT JOIN Customers c ON c.customer_id = o.customer_id
LEFT JOIN Products p ON p.product_id = o.product_id
GROUP BY c.customer_name
ORDER BY COUNT(DISTINCT p.category_id) DESC
Then depending on your RDBMS flavor, add a TOP or a LIMIT.

Related

How to sort customer names by items purchased in SQL

Sorry new to this but,
I need to sort customer names by total quantity of items purchased by them, in desc order.
the purchased amount in the table is known as Inv_number
I would need the customer name and than the sum. This is what it should be
Thanks
I don't know what your tables are named or what fields they have on them, so I'll give a generic example:
SELECT c.CUST_NAME AS "cust_name",
SUM(oi.QTY_PURCHASED) AS "sum"
FROM CUSTOMERS c
INNER JOIN ORDERS o
ON o.ID_CUSTOMERS = c.ID_CUSTOMERS
INNER JOIN ORDER_ITEMS oi
ON oi.ID_ORDERS = o.ID_ORDERS
GROUP BY c.CUST_NAME
ORDER BY SUM(oi.QTY_PURCHASED) DESC,
c.CUST_NAME ASC
db<>fiddle here
Should work this way - you have to join the tables for customerinfo (customer in this script) and the items purchased (order_items). For simplicity I only made an example with two tables. if the customer_id is present in a kind of "order" table, you have to join order_items -> order -> customer
SELECT
x.customer_name,
y.customer_amount
FROM customer x
INNER JOIN (
SELECT
customer_id,
SUM(order_amount) AS customer_amount
FROM order_items
GROUP BY customer_id
) y ON x.id = y.customer_id
ORDER BY y.customer_amount DESC;

Query between 2 tables

I need to write a query between 2 tables that allow me know the total per SKUs.
Table 1: order_item
order_item_id(pk) order_id product_id qty_ordered total
Table 2:product
product_id SKU name price
I've tried the following:
from product
select SKU
Natural Join order_item
SELECT sum(qty_ordered), p.name, p.SKU
FROM product p
JOIN order_item o
ON p.product_id = o.product_id
group by
p.name, p.SKU
Useful link on aggregates and grouping: https://www.w3schools.com/sql/sql_groupby.asp

select different data from several tables

How could I select
| Customer_name | Num_of_AllTime_Orders | Num_of_different_Products_That_Customer_Ordered |
as a table when each data is from a different table?
I tried to count customers, join tables and group by... but no luck.
SELECT CompanyName, count(Customer_ID) from dbo.CUSTOMERS join dbo.ORDERS on CUSTOMERS.Customer_ID=ORDERS.CustomerID
Customers_Table:
CustomerID | Customer_Name
Orders_Table:
OrderID| Customer_ID
Order_Detail_Table:
OrderID| Product_ID |
I expect the output of a table which has these columns :
1. Customer_Name
2. Num_of_AllTime_Orders - how many orders that costumer made?
3. Num_of_different_Products_That_Customer_Ordered - how many different products that customer ordered?
Select CUSTOMERS.Customer_Name
,count(distinct ORDERS.OrderID) as Num_of_AllTime_Orders
,count(distinct Order_Detail_Table.Product_ID) as Num_of_different_Products_That_Customer_Ordered
from dbo.CUSTOMERS
join dbo.ORDERS on CUSTOMERS.CustomerID = ORDERS.Customer_ID
join dbo.Order_Detail_Table on ORDERS.OrderID = Order_Detail_Table.OrderID
group by CUSTOMERS.Customer_Name
SELECT Company_Name = C.CompanyName, NumOfOrders = COUNT (DISTINCT O.OrderID), NumOfProducts = COUNT (DISTINCT OD.ProductID)
FROM dbo.CUSTOMERS AS C JOIN ORDERS AS O ON C.Customer_ID=O.CustomerID JOIN ORDERDETAILS AS OD ON OD.OrderID=O.OrderID
GROUP BY C.CompanyName
ORDER BY 1

Select all orders by one customer

I have three tables, orders, orders_details and customers. I need to select orders by one customer for the orders table so I did this
orders columns:
id
customer_id
created
vat
discount
amount
paid
orders_details columns:
id
order_id
cost
qty
product
The SQL I used
SELECT
orders.*,
SUM(orders_details.qty*orders_details.cost) as amount,
SUM(orders_details.qty) AS qty
FROM
orders,
orders_details,
customers
WHERE
orders.customer_id = customers.id
AND orders_details.order_id = orders.id
AND orders.customer_id = 1
but I am getting a wrong qty of 30 instead of 20 and the amount is wrong
If you want to aggregate per order you need a GROUP BY clause. Also you should use proper JOIN syntax, and might consider using aliases to make the query more compact.
SELECT
o.*,
SUM(od.qty * od.cost) AS amount,
SUM(od.qty) AS qty
FROM orders o
INNER JOIN orders_details od ON od.order_id = o.id
INNER JOIN customers c ON o.customer_id = c.id -- not used, might be excluded
WHERE o.customer_id =1
GROUP BY o.id
Depending on what database system you are using you might need to include all columns referenced in o.* in the GROUP BY:
GROUP BY o.id, o.customer_id, o.created, o.vat, o.discount, o.amount, o.paid
Last note: as you don't seem to use any data from the customers table you probably could exclude that table altogether.
You're missing a GROUP BY clause which I'm guessing should be on orders.id.

SQL Server query to find the total price of all the products by order

I have a table Orders with (id,orderCode,productId,quantity,color,size)
where I can have entries like:
1,O20100812,163,2,BLUE,Medium
1,O20100812,163,3,BLUE,Larger
1,O20100812,145,4,RED,Large etc
1,O20100815,134,5,RED,Large etc
1,O20100815,143,2,BLACK,Large etc
1,O20100815,112,8,BLACK,Large etc
And another table Products with (id,name,price)
What I want is to find the total price of all the products in the order with orderCode 020100812. Should I DISTINCT select the order code and then SUM the quantity while JOINing the products table?
Why you need distinct?
Select SUM(o.Quantity * Price) TotalPrice
FROM Orders o JOIN Products p ON (o.ProductId = p.Id)
WHERE OrderCode = '020100812'
For all orders you can use the following query:
Select OrderCode, SUM(o.Quantity * Price) TotalPrice
FROM Orders o JOIN Products p ON (o.ProductId = p.Id)
Group by OrderCode
No, GROUP BY and then you can use SUM to aggregate across the group, e.g.
select O.id, O.ordercode, sum(P.price * O.quantity) as total
from orders O
join products P on P.id = O.productid
group by O.id, O.ordercode
which will show you the total price for each order code within each order - if you wanted all order codes across all orders you'd need
select O.ordercode, sum(P.price * O.quantity) as total
from orders O
join products P on P.id = O.productid
group by O.ordercode
i.e. don't group in the order ID.
(I'm guessing that O20100812 was just an example and you actually want this for all order codes?)