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
Related
Let's say I have three tables to manage purchases from my online shop:
Products: with columns ID, Name, Price
Customers: with columns ID, Name
Purchases: with columns ProductID, CustomerID, PurchaseDate
Now, how would I go about retrieving products purchased by more than N distinct customers?
I've tried the following on SQL Server 2019 Trial Edition but I'm getting a syntax error on COUNT.
SELECT ProductID, CustomerID, COUNT(*) as C
FROM Purchases
GROUP BY ProductID, CustomerID
HAVING C > 100
ORDER BY C DESC
Better still, how would I go about retrieving products purchased by more than N distinct customers over a 30-day period?
Thanks for any help and/or pointers.
With your current query, you are just counting how often each customer bought each product, because you are grouping by the combination of productid and customerid. Furthermore you cannot reference to the column alias for the count in the HAVING or ORDER BY clause
Try this
declare #purchasedatelower datetime = dateadd(day, -30, getdate())
declare #purchasedateupper datetime = getdate()
declare #distinctcustomers int = 100
select productid, count(distinct customerid) as customercount
from purchases
where purchasedate between #purchasedatelower and #purchasedateupper
group by productid
having count (distinct customerid) >= #distinctcustomers
order by count(distinct customerid) desc
This will return all products, which have been bought by at least 100 distinct customers, in the last 30 days, together with the distinct number of customers.
Try to order them by COUNT()
SELECT ProductID, CustomerID
FROM Purchases
GROUP BY ProductID, CustomerID
HAVING COUNT(*) > 100
ORDER BY COUNT(*) DESC
Now, how would I go about retrieving products purchased by more than N distinct customers?
You would use COUNT(DISTINCT):
SELECT ProductID, COUNT(DISTINCT CustomerID) as num_customers
FROM Purchases
GROUP BY ProductID
HAVING COUNT(DISTINCT CustomerID) > 100
ORDER BY COUNT(DISTINCT CustomerID) DESC;
If you have a particular period in mind, then add a WHERE clause before the GROUP BY.
DECLARE #Popularity int = 1
DECLARE #MonthsAgo int = 1
SELECT p.ProductId, p.ProductName, pc.CustomersDistinct
FROM (
-- Sub-query to compute the aggregate.
-- Count the number of distinct customers that purchased each product.
SELECT ProductId, COUNT(DISTINCT CustomerId) AS CustomersDistinct
FROM Purchases
WHERE PurchaseDate >= DATEADD(MONTH, -#MonthsAgo, CURRENT_TIMESTAMP)
GROUP BY ProductId
HAVING COUNT(DISTINCT CustomerId) > #Popularity
) AS pc
-- Now do JOINs to look up helpful values for the final SELECT list.
INNER JOIN Products p ON pc.ProductId = p.ProductId
ORDER BY 3 DESC
I have a SQL database with a list of Customer IDs CustomerID and invoices, the specific product purchased in each invoice ProductID, the Date and the Income of each invoice . I need to write a query that will retrieve for each product, which was the second customer who made a purchase
How do I do that?
EDIT:
I have come up with the following query:
SELECT *,
LEAD(CustomerID) OVER (ORDER BY ProductID, Date) AS 'Second Customer Who Made A Purchase'
FROM a
ORDER BY ProductID, Date ASC
However, this query presents multiple results for products that have more than two purchases. Can you advise?
SELECT a2.ProductID,
(
SELECT a1.CustomerID
FROM a a1
WHERE a1.ProductID = a2.ProductID
ORDER BY Date asc
LIMIT 1,1
) as SecondCustomer
FROM a a2
GROUP BY a2.ProductID
I need to write a query that will retrieve for each product, which was the second customer who made a purchase
This sounds like a window function:
select a.*
from (select a.*,
row_number() over (partition by productid order by date asc) as seqnum
from a
) a
where seqnum = 2;
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.
How do i combine a SUM and MAX in a single query?
Lets say i have a orderrule:
ProductID \ Quantity
I Could say:
Select ProductID,SUM(Quantity) AS Sold
FROM Orderrule
GROUP BY ProductID
ORDER BY SUM(Quantity) Desc
However that would return all sales, and not just the most sold product (with quantity).
Try this
SELECT TOP(1)
*
FROM
(
Select
ProductID,
MAX(Quantity) As MaxQuantity,
SUM(Quantity) AS Sold
FROM Orderrule
GROUP BY ProductID
)AS X
ORDER BY Sold DESC
So there are two ways to do it - first to have a limit on the number of results, something likes:
select * from (your_select) where rownum = 1
the other one is to pick the one with the the highest value, which will require a subselect, something like:
having sum(quantity) =
(select max(sum_quan) from (select sum(Quantity) from orderrule group by Product_id))
SELECT TOP 1 ProductID, Sold FROM
(
SELECT ProductID, SUM(Quantity) AS Sold
FROM Orderrule
GROUP BY ProductID
) totals
ORDER BY Sold DESC
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