SQL Server : TOP along with Distinct - sql

I have two tables Products and PurchaseDetails.
The schema for Products table is
ProductId (primary key)
ProductName
CategoryId
Price
QuantityAvailable
The schema for PurchaseDetails table is
PurchaseId
EmailId
ProductId
QuantityPurchased
DateOfPurchase
The question asks me to find out the TOP 3 products that are purchased in large quantity.
I wrote this SQL query:
Select TOP 3
Distinct(ProductName), Price, QuantityPurchased
from
Product, PurchaseDetails
where
Product.ProductId = PurchaseDetails.ProductId
order by
QuantityPurchased DESC
But the above query throws an error. I fail to see why the error is being generated by the above query ?

Below query will give you the top 3 products that are purchased in large quantity
Select TOP 3 ProductName,sum(Price) as [price],sum(QuantityPurchased) as QuantityPurchased
from Product , PurchaseDetails
where Product.ProductId=PurchaseDetails.ProductId
group by ProductName
order by QuantityPurchased DESC

Select TOP 3 ProductName,sum(Price) as [price],sum(QuantityPurchased) as QuantityPurchased
from Product , PurchaseDetails
where Product.ProductId=PurchaseDetails.ProductId
group by ProductName
order by QuantityPurchased DESC

Related

Get the date for each duplicated row in SQL Server

I've made a query to get how many products are sold more than one time and it worked.
Now I want to show the transaction date for each of these duplicated sales, but when I insert the date on the select it brings me a lot less rows: something is going wrong. The query without the date returns 9855 rows and with the date just 36 rows.
Here is the query I'm doing:
SELECT TransactionDate,
ProductName,
QtyOfSales = COUNT(*)
FROM product_sales
WHERE ProductID = 1 -- Product Sold ID
AND ProductName IS NOT NULL
GROUP BY ProductName,
TransactionDate
HAVING COUNT(*) > 1
Perhaps a subquery? Can you help in that regard?
You can use the corresponding COUNT window function, that will find the amount of transactions by partitioning on the "ProductName" as required:
WITH cte AS(
SELECT TransactionDate,
ProductName,
COUNT(*) OVER(PARTITION BY ProductName) AS QtyOfSales
FROM product_sales
WHERE ProductID = 1 -- Product Sold ID
AND ProductName IS NOT NULL
)
SELECT DISTINCT TransactionDate,
ProductName
FROM cte
WHERE QtyOfSales > 1

Retrieve top selling products

I would like to receive top 5 selling products in quantity in an order from NorthWind database.
The database has a bunch of tables like Order, OrderDetails, Customers, etc. I was suggested to use Orders Details table below:
Now, I tried the following:
WITH cte AS (
SELECT
OrderID,
Quantity,
ProductID,
ROW_NUMBER() OVER(PARTITION BY OrderID ORDER BY OrderID) as row_num
FROM [Order Details]
)
SELECT *
FROM cte
WHERE row_num IN (SELECT row_num FROM cte WHERE row_num <=10)
ORDER BY OrderID;
Thought this retrieves 10 rows now for each order, they are not ordered based on sold quantities and top sold products are not retrieved properly as for some orders the top sold was beyond the first top 10 rows based on row number I got with ROW_NUMBER() function in SQL.
Edit: For example, if I have 10 orders each with 20 products, then I want top 5 each each product, so the result table should have 50 rows total.
After your edits:
WITH cte AS (
SELECT
OrderID,
Quantity,
ProductID,
ROW_NUMBER() OVER(PARTITION BY OrderID ORDER BY Quantity DESC) as row_num
FROM [Order Details]
)
SELECT *
FROM cte
WHERE row_num <= 5
ORDER BY OrderID;
You should do a
SELECT DISTINCT productid FROM OrderDetails ORDER BY quantity GROUP BY productId LIMIT 5
At least this is the mysql syntax.

SQL query to find sum using group by

SQL query to find sum of quantity of similar prodid only if quantity in each prodid greater than 1.
SQL query:
Select ProdID,sum(quantity)
From product
Where quantity >1
Group by ProdID
What logical error in above query ??
The Result should be :
ProdID Quantity
------ --------
102 11
For such purpose include also quantity column in the group by expression with having clause
Select ProdID,quantity
from product
group by ProdID, quantity
having sum(quantity) >1
Edit ( due to your last comment ) : Use not in as below
Select ProdID, sum(quantity)
from product
where ProdID not in ( select ProdID from product p where quantity = 1 )
group by ProdID
Rextester Demo
You can use filtering in the having:
Select ProdID, sum(quantity)
from product
group by ProdID
having min(quantity) > 1;
The use of min() assumes that quantity is non-negative.

Select subset from subset

Data has 1 table with 2 relevant fields:
OrderNumber
ProductID
How do I structure sql to find :-
Select All OrderNumber where ProductID in (A,B)
Now, on this subset, Select all where ProductID in (A,B,C,D,E)
Show CustomerName, OrderNumber, ProductID, ProductPrice
Goal is to find all Orders that contain 2 specific products, then to measure sales of only 3 specific products related to A,B.
I'm not sure what you want, but I will take a stab.
This will show you the details of orders with one of the 5 product id's
SELECT CustomerName, OrderNumber, ProductID, ProductPrice
FROM yourTable
WHERE ProductId IN ('A','B','C','D','E')
This will count the orders for you
SELECT ProductID, COUNT(*) AS Count
FROM yourTable
WHERE ProductId IN ('A','B','C','D','E')
GROUP BY ProductId

SQL GROUP BY on a sub query

I have a query that will return results from 2 tables into 1 using a UNION ALL, which all works as I need it to. However I need to run a GROUP BY and an ORDER BY on the returned dataset however I am getting many errors and I'm not sure how to solve it.
Here is my Query:
SELECT ProductID, Quantity
FROM BasketItems
UNION ALL
SELECT ProductID, Quantity
FROM OrderItems
This will return a results set such as this:
ProductID Quantity
15 2
20 2
15 1
8 5
5 1
I then want to run a GROUP BY on the ProductID field and then finally an ORDER BY DESC on the Quantity field. So in the final output, this particular results set will finally result in this:
ProductID
8
15
20
5
I can then run queries on this result set as I usually do
EDIT:
As stated above, but maybe not implied enough is that I will need to run queries on the returned results, which isn't working as you cannot run a query on a set of results that have an ORDER BY clause (so far as I gathered from the error list)
If you want more information on the problem, here it is:
From this results set, I want to get the products from the product table that they relate to
SELECT * FROM Products WHERE ID IN (
SELECT ProductID
FROM
(
SELECT ProductID, Quantity
FROM BasketItems
UNION ALL
SELECT ProductID, Quantity
FROM OrderItems
) v
GROUP BY ProductID
ORDER BY SUM(Quantity) DESC
)
However, I get this error: The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified.
The output of products need to be in the order that they are returned in the sub query (By quantity)
SELECT Products.*
FROM Products
INNER JOIN
(
SELECT ProductID, Sum(Quantity) as QuantitySum
from
(
SELECT ProductID, Quantity
FROM BasketItems
UNION ALL
SELECT ProductID, Quantity
FROM OrderItems
) v
GROUP BY ProductID
) ProductTotals
ON Products.ID = ProductTotals.ProductID
ORDER BY QuantitySum DESC
will this work?
SELECT ProductID
from
(
SELECT ProductID, Quantity
FROM BasketItems
UNION ALL
SELECT ProductID, Quantity
FROM OrderItems
) temp
GROUP BY temp.ProductID
ORDER BY SUM(temp.Quantity) desc
Here's a cte version (no live test so please excuse blunders)
EDIT
;WITH myInitialdata_cte(ProductID,Quantity)
AS
(
SELECT ProductID, Quantity FROM BasketItems
UNION ALL
SELECT ProductID, Quantity FROM OrderItems
)
SELECT b.ID
FROM
myInitialdata_cte a
INNER JOIN Products b ON
a.ProductID = b.ID
GROUP BY ProductID
ORDER BY SUM(a.Quantity) DESC