product which has sold the most inner join - sql

I need to show the most popular selling item from the products table joining the sales table.
I need to display the most popular selling items.
Here's the code I've tried :
SELECT products.prod_id, products.prod_name, sales.quantity,
FROM products
INNER JOIN sales ON products.prod_id = sales.prod_id
Here are pics products and sales
products
sales

SELECT products.prod_id, products.prod_name, SUM(sales.quantity) as sales_total,
FROM products
INNER JOIN sales ON products.prod_id = sales.prod_id
GROUP BY products.prod_id, products.prod_name
ORDER BY sales_total DESC

SELECT products.prod_id, products.prod_name, sum(sales.quantity) as sales_total
FROM products
INNER JOIN sales ON products.prod_id = sales.prod_id
GROUP BY products.prod_id, products.prod_name

SELECT products.prod_id, products.prod_name, SUM(sales.quantity),
FROM products
INNER JOIN sales ON products.prod_id = sales.prod_id
GROUP BY prod_id
ORDER BY 3 DESC
LIMIT 25
You will want an index such as (prod_id, quantity) on sales.

SELECT b.prod_id, p.prod_name, b.Qty
FROM (
SELECT a.prod_id, a.Qty, MAX(a.Qty) OVER () AS MaxQty
FROM (
SELECT s.prod_id, SUM(s.quantity) AS Qty
FROM sales s
GROUP BY s.prod_id ) a ) b
INNER JOIN Products p ON p.prod_id = b.prod_id
WHERE b.Qty = b.MaxQty

Related

Find employee who made highest sales to the customer who made most purchases

I'm having trouble with this question in my Database homework And need to answer this question:
Which employee has the highest sales to the customer who has made the most purchases?
And these are my database tables
And these are my attempts to write this query
--select Customers.Firstname,Products.Name,Sales.Quantity from Customers
--inner join Sales
--on Customers.CustomerId=Sales.CustomerId
--inner join Products
--on Sales.productId=Products.ProductId
--where Products.Name like 'Mobile'
--Select Customers.CustomerId,max(COUNT(Customers.CustomerId)) As Customecount,Emploees.EmploeeId,max(COUNT(Emploees.EmploeeId))as EmploeeeCount from Emploees
--inner join Sales
--on Emploees.EmploeeId=Sales.EmploeeId
--inner join Customers
--on Customers.CustomerId=Sales.CustomerId
--group by Customers.CustomerId,Emploees.EmploeeId ,Count(Sales.productId)as productCount,Count(Emploees.EmploeeId)as emploeeCount,Count(Customers.CustomerId)as customerCount
select * from
(select Distinct Customers.CustomerId,Sales.productId,COUNT(Sales.productId)as CountProduct from Customers
inner join Sales
on Customers.CustomerId=Sales.CustomerId
inner join Emploees
on Emploees.EmploeeId=Sales.EmploeeId
group by Sales.productId,Emploees.EmploeeId,Customers.CustomerId,Sales.productId) as Result
--gr
But these don't work
Please, help me to write this Query.
Try to solve the problem step by step. Find the customer id with most orders by total:
SELECT TOP 1 sales.customerid
FROM sales
JOIN products ON sales.productid = products.productid
GROUP BY sales.customerid
ORDER BY SUM(sales.quantity * products.price) DESC
Next step is to find the employee with most sales by count to that customer (changing it to by total is trivial):
SELECT TOP 1 sales.salespersonid
FROM sales
WHERE sales.customerid = (
SELECT TOP 1 sales.customerid
FROM sales
JOIN products ON sales.productid = products.productid
GROUP BY sales.customerid
ORDER BY SUM(sales.quantity * products.price)
)
GROUP BY sales.salespersonid
ORDER BY COUNT(sales.salesid) DESC
Finally select the employee record:
SELECT *
FROM employee
WHERE employeeid = (
SELECT TOP 1 sales.salespersonid
FROM sales
WHERE sales.customerid = (
SELECT TOP 1 sales.customerid
FROM sales
JOIN products ON sales.productid = products.productid
GROUP BY sales.customerid
ORDER BY SUM(sales.quantity * products.price)
)
GROUP BY sales.salespersonid
ORDER BY COUNT(sales.salesid) DESC
)
Maybe something like this....
First get the customer with most purchases and then find all employees who have sold to that customer and return the top 1 employee with the most sales.
SELECT TOP (1)
e.EmploeeId
, SUM(s.quantity * p.Price) TotalSales
FROM Emploees e
inner join Sales s ON e.EmploeeId = s.EmploeeId
inner join Product p ON s.productId = s.productId
WHERE s.CustomerId = (
-- Get the customer with most purchases
SELECT TOP (1) x.CustomerId
FROM ( SELECT
c.CustomerId
, SUM(s.quantity * p.Price) TotalSales
FROM Customers c
inner join Sales s ON c.CustomerId = s.CustomerId
inner join Product p ON s.productId = o.productId
GROUP BY c.CustomerId
) x
ORDER BY TotalSales DESC
)
GROUP BY e.EmploeeId
ORDER BY TotalSales DESC
To find Most Sales and Purchases by count (Number of sales/Purchases) following query will do the trick:
SELECT TOP (1)
e.EmploeeId
, COUNT(*) TotalSales
FROM Emploees e
inner join Sales s ON e.EmploeeId = s.EmploeeId
WHERE s.CustomerId = (
SELECT TOP (1) x.CustomerId
FROM ( SELECT
c.CustomerId
, COUNT(*) TotalSales
FROM Customers c
inner join Sales s ON c.CustomerId = s.CustomerId
GROUP BY c.CustomerId
) x
ORDER BY TotalSales DESC
)
GROUP BY e.EmploeeId
ORDER BY TotalSales DESC
In one of the comments you said that "most sales" mean more sale quantity. This answer takes this criteria into consideration.
SELECT TOP (1) SalesPersonID,
(FirstName + ' ' + MiddleName + ' ' + LastName) AS EmployeeName
FROM Sales S
JOIN Employees E ON S.SalesPersonID = E.EmployeeID
WHERE CustomerID =
(
-- Sub-query that returnes CustomerID with most quantities bought
SELECT TOP (1) CustomerID
FROM Sales
GROUP BY CustomerID
ORDER BY SUM(Quantity) DESC
)
GROUP BY SalesPersonID,
(FirstName + ' ' + MiddleName + ' ' + LastName)
ORDER BY SUM(Quantity)

I am having trouble finding the average sales of all shops

I can't seem to find a solution on how to receive the sales of the shops that are bigger than the average of all shops.
I have already tried some ways and managed to get the average sales of each shop. I have then tried to get the shops that have sales bigger than the average of all shops but have failed.
SELECT SALES, (SELECT AVG(AVERSALES * SALES)) AS AVGSALES FROM
(
SELECT
Shops.NAME,
SUM(InvDet.QTY * Products.PRICE ) AS SALES,
AVG(InvDet.QTY * Products.PRICE) AS AVERSALES
FROM
Invoices
INNER JOIN InvDet ON Invoices.INV_ID = InvDet.INV_ID
INNER JOIN Products ON InvDet.PR_ID = Products.PR_ID
INNER JOIN Shops ON Shops.S_ID=Invoices.S_ID
WHERE
Invoices.INVOICE_DATE BETWEEN '2013-06-24' AND '2013-06-30'
GROUP BY Shops.NAME
)AS SALES_TABLE
GROUP BY SALES
HAVING SALES > (SELECT AVG(AVERSALES))
You have many ways to get what you are looking for.
One of them should be this:
select
s.name,
s.SALES
from (
select
s.name,
sum(i.QTY * p.PRICE) AS SALES
from Invoices i
join InvDet id ON i.INV_ID = id.INV_ID
join Products p ON id.PR_ID = p.PR_ID
join Shops s ON s.S_ID=i.S_ID
where i.INVOICE_DATE BETWEEN '2013-06-24' AND '2013-06-30'
group by s.name
) s
join (
select avg(i.QTY * p.PRICE) as average
from Invoices i
join InvDet id ON i.INV_ID = id.INV_ID
join Products p ON id.PR_ID = p.PR_ID
-- If you want to compare with the total average
-- remove this where part
where i.INVOICE_DATE BETWEEN '2013-06-24' AND '2013-06-30'
) a
on s.SALES>a.average
This other approach (for me clearer) must return the same:
declare #average float
select #average=avg(i.QTY * p.PRICE)
from Invoices i
join InvDet id ON i.INV_ID = id.INV_ID
join Products p ON id.PR_ID = p.PR_ID
-- If you want to compare with the total average
-- remove this where part
where i.INVOICE_DATE BETWEEN '2013-06-24' AND '2013-06-30'
select
s.name,
sum(i.QTY * p.PRICE) AS SALES
from Invoices i
join InvDet id ON i.INV_ID = id.INV_ID
join Products p ON id.PR_ID = p.PR_ID
join Shops s ON s.S_ID=i.S_ID
where i.INVOICE_DATE BETWEEN '2013-06-24' AND '2013-06-30'
group by s.name
having sum(i.QTY * p.PRICE)>#average
There are other choices (for example a common table expression would fit well here too). I think with these two is enough to solve your question. I hope they fit with what you need.
I am not sure about your requirement
SELECT SALES, (SELECT AVG(AVERSALES * SALES)) AS AVGSALES FROM
(
SELECT
Shops.NAME,
SUM(InvDet.QTY * Products.PRICE ) AS SALES,
AVG(InvDet.QTY * Products.PRICE) AS AVERSALES
FROM
Invoices
INNER JOIN InvDet ON Invoices.INV_ID = InvDet.INV_ID
INNER JOIN Products ON InvDet.PR_ID = Products.PR_ID
INNER JOIN Shops ON Shops.S_ID=Invoices.S_ID
WHERE
Invoices.INVOICE_DATE BETWEEN '2013-06-24' AND '2013-06-30'
GROUP BY Shops.NAME
)AS SALES_TABLE
GROUP BY SALES
HAVING SALES > AVERSALES

inner join sales and products

hi i am having a problem with an inner join on my products and sales table i need to display a list of all the sales and also list the products which havn't been selling
this is the cod i have been trying-->
SELECT
products.prod_id,
products.prod_name,
sales.date_of_sale,
FROM
products
INNER JOIN
sales
ON
products.prod_id = sales.prod_id;
here is a picture of products table
here is a picture of the sales table
any help would be greatly appreciated.. thank you very much ..
To display the product and its sales
SELECT products.prod_id,
products.prod_name,
sales.date_of_sale
FROM products
INNER JOIN sales
ON products.prod_id = sales.prod_id;
To display products which don't have sales
SELECT products.prod_id,
products.prod_name
FROM products
WHERE NOT EXISTS (SELECT 1
FROM sales
WHERE products.prod_id = sales.prod_id);
If you want select in a single query
SELECT products.prod_id,
products.prod_name,
sales.date_of_sale
FROM products
LEFT OUTER JOIN sales
ON products.prod_id = sales.prod_id;

SQL nested SELECT with JOIN

I wasted all the day on one query without success , SOS I need a help :) with a given #CustomerId , I need to query all the Products that linked to customer seller can sell but not sold to him before , the Commissions table is indication of what products seller can sell
Thanks in advance
SELECT sellableProduct
FROM (SELECT Comissions.ProductId AS sellableProduct, Sellers.SellerId AS sellableSeller FROM Comissions INNER JOIN Sellers ON Comissions.SellerId=Sellers.SellerId INNER JOIN Customers ON Sellers.SellerId=Customers.SellerId WHERE Customers.CustomerId = #customerid) AS tblSellable
LEFT JOIN (SELECT Sales.ProductId AS soldProduct, Customers.SellerId as soldSeller FROM Customers INNER JOIN Sales ON Customers.CustomerId=Sales.CustomerId WHERE Customers.CustomerId = #customerid) AS tblSold
ON tblSellable.sellableProduct=tblSold.soldProduct AND tblSellable.sellableSeller=tblSold.soldSeller
WHERE tblSold.soldProduct IS NULL
this way you avoid time-consuming IN statements
If a Customer can only have one Seller, then you can omit the seller link:
SELECT sellableProduct
FROM (SELECT Comissions.ProductId AS sellableProduct FROM Comissions INNER JOIN Sellers ON Comissions.SellerId=Sellers.SellerId INNER JOIN Customers ON Sellers.SellerId=Customers.SellerId WHERE Customers.CustomerId = #customerid) AS tblSellable
LEFT JOIN (SELECT Sales.ProductId AS soldProduct FROM Sales WHERE Sales.CustomerId = #customerid) AS tblSold
ON tblSellable.sellableProduct=tblSold.soldProduct
WHERE tblSold.soldProduct IS NULL
Basically, you're looking for products that have a record in commissions, but not in sales. Using :id to denote the specific ID:
SELECT *
FROM products
WHERE productid IN (SELECT productid
FROM commissions
WHERE sellerid = :id) AND
productid NOT IN (SELECT productid
FROM sales
JOIN customers ON sales.customerid = cusomers.customerid
WHERE sellerid = :id)
Would this work?
SELECT sell.*, prod.* FROM
Sellers sell
INNER JOIN Customers cust ON cust.SellerId = sell.SellerId
LEFT JOIN Commissions comm ON sell.SellerId = comm.SellerId
LEFT JOIN Products prod ON prod.ProductId = comm.ProductId
WHERE prod.ProductId NOT IN (
SELECT ProductId
FROM Products p INNER JOIN
Sales s ON s.ProductId = p.ProductId
WHERE s.CustomerId = #CustomerId
It get all the sellers and the respective product from commission, where the product Id is NOT associated with any sale of the client

How do I select max date for each row from a subquery

Let's say I want to select the 3 bestsellers in a supermarket. To do this, I have to add each sale to get the total for each product:
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC
It then returns me something like this:
ID..|.Name.|.totalsales
55.|.milk....|.1000
24.|.candy.|.800
67.|.juice...|.500
Now I want to retrieve a 4th column containing the last sale from each of these items, like querying "MAX saledate" to each one. How do I accomplish that?
EDIT: Adding MAX(s.saledate) isn't helping. It retrieves a date like 01 Jan 2012 to all rows, but if I query MAX(s.saledate) individually for each entry of the table above, it returns the correct date... My question is, how can I add the column MAX(s.saledate) for each product, using the same query that shows the 3 bestsellers.
You could add max(s.saledate) to your query. The subquery is not needed. The syntax t1 join t2 on <predicate> is considered much more readable than from t1, t2 where <predicate>.
select top 3 sum(s.individual_sale) as totalsales
, p.productID as ID,
, p.productName as Name
, max(s.saledate) as MaxSaleDate
from sales s
join products p
on p.productID = s.productID
group by
p.productID
, p.productName
order by
sum(s.individual_sale) desc
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name,
MAX(s.saledate) as MaxSaleDate
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC
Add MAX(saledate) to your exisitng query.
SELECT TOP(3) *
FROM
(
SELECT
SUM(s.individual_sale) AS totalsales,
p.productID AS ID,
p.productName AS Name,
MAX(saleDate)
FROM
sales s,
products p
WHERE
1=1
AND p.productID = s.productID
GROUP BY
p.productID,
p.productName
) AS top_sellers
ORDER BY
top_sellers.totalsales DESC