I have three sets of information:
productID
date
seller
I need to get information of last product sold for each productID and sold by. I tried using max value of date but that forces me to use grouping for seller as well but I don't want to group by seller. I want to group by productID, get the date it was sold last and by who. How can I avoid grouping on seller?
Use Window function which will help you to find the Latest date in each group(productId)
SELECT ProductID,
[date],
seller
FROM (SELECT Row_number()
OVER(
partition BY ProductID
ORDER BY [date] desc) Rn,
*
FROM tablename) a
WHERE rn = 1
or use can also use Max aggregate with group by to get the result
SELECT ProductID,
[date],
seller
FROM tablename a
JOIN (SELECT Max([date]) [date],
productid
FROM tablename
group by productid) b
ON a.productid = b.productid
AND a.[date] = b.[date]
Related
I am learning SQL server and I am stuck on a question.
I need to write a query that shows each customers last order that he placed and the order before the last one he made.
Thank you for your help!
Edit: So far I have this:
SELECT SalesOrderID, CustomerID, per.FirstName, per.LastName, OrderDate as "Latest Order Date"
FROM (
SELECT *,
Row_Number() OVER (PARTITION BY CustomerID ORDER BY OrderDate desc) as 'Rank'
FROM sales.SalesOrderHeader head
) a join Person.Person per
on CustomerID = per.BusinessEntityID
WHERE Rank = 1
As you can see, I am pretty close. I just need to add a column that shows the order before the latest order date.
Sorry, I'm new to the site (long time viewer, first time poster)
ty!
You need to combine both ROW_NUMBER and LEAD
LEAD is better in this case, because LAG needs the rows sorted in the opposite direction from the ROW_NUMBER
SELECT head.SalesOrderID, CustomerID, per.FirstName, per.LastName, OrderDate as LastOrder, head.PreviousOrder
FROM (
SELECT *,
ROW_NUMBER() OVER (PARTITION BY CustomerID ORDER BY OrderDate DESC) as rnk,
LEAD(OrderDate) OVER (PARTITION BY CustomerID ORDER BY OrderDate DESC) as PreviousOrder
FROM sales.SalesOrderHeader head
) head
JOIN Person.Person per ON head.CustomerID = per.BusinessEntityID
WHERE head.rnk = 1;
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;
I am trying to find the top seller here. I was trying to use the below but i dont think this is right. I can see other ids that have bigger totals plus i think i should be using a SUM function instead of MAX.
select selleruserid
from sales_fact
where price = (select max(price) from sales_fact)
As I understand it you want to get the total sales of each seller and choose the seller who has the most sales.
The seller who has the most sales:
SELECT max(totalPrice) as totalPrice,selleruserid
FROM (SELECT sum(price) AS totalPrice,selleruserid FROM sales_fact GROUP BY selleruserid)
Total sales of each seller:
SELECT totalPrice as totalPrice,selleruserid
FROM (SELECT sum(price) AS totalPrice,selleruserid FROM sales_fact GROUP BY selleruserid)
You can use FETCH clause with TIES option as follows:
select selleruserid, sum(price) as total
from sales_fact
group by selleruserid
order by sum(price) desc
FETCH FIRST 1 ROW WITH TIES
OR You can use the analytical function RANK as follows:
select selleruserid, total from
(select selleruserid, sum(price) as total,
RANK() OVER (ORDER BY sum(price) DESC) AS rn
from sales_fact
group by selleruserid) t
where rn = 1
I am trying to fetch the Date and VisitorID from a payment table having the maximum value of amount. I know how to find max value by each date but I am unable to fetch the Date and VisitorID having the maximum value of amount.
I tried to use the attached code below but I just get one value having max value. I am trying to get date and visitor ID from each day with maximum value of amount.
SELECT Date, visitorID
FROM payment
WHERE Amount =
(
SELECT MAX(Amount)
FROM payment
)
You can try using correlated subquery
SELECT Date, visitorID,amount
FROM payment a
WHERE exists
(
SELECT 1
FROM payment b where a.date=b.date group by b.date having max(b.amount)=a.amount
)
One option uses a subquery:
SELECT p1.Date, p1.visitorID
FROM payment p1
INNER JOIN
(
SELECT Date, MAX(Amount) AS max_amount
FROM payment
GROUP BY Date
) p2
ON p1.Date = p2.Date AND p1.Amount = p2.max_amount;
The subquery finds, for each date, the maximum amount. Then, we join this to your original table to effectively filter off any record for a given date which does not have the maximum amount.
If your version of SQL supports analytic functions, then we can use them instead:
SELECT Date, visitorID
FROM
(
SELECT p.*, ROW_NUMBER() OVER (PARTITION BY Date ORDER BY Amount DESC) rn
FROM payment p
) t
WHERE rn = 1;
If you also wanted to have all records for a given date which are tied for the highest amount, then replace ROW_NUMBER above with either RANK or DENSE_RANK.
After seeing your comments it seems you need row_number()
with cte as
(
SELECT *,row_number() over(partition by date order by amount desc)rn
from payment t1
) select * from cte where cte.rn=1
You were close, you need reference from the outerquery to make it correlated subquery :
SELECT p.Date, p.visitorID
FROM payment p
WHERE p.Amount = (SELECT MAX(p1.Amount) FROM payment p1 WHERE p1.Date = p.Date);
I have a basic order detail table that contains: docDate, customerCode, itemCode, Price, and Quantity. Looked through a number of similar questions, but they didn't seem to take into account everything I need, and I failed to re-purpose the other solutions.
The end goal: Only the most recent record of each individual item ever bought by a customer. (So one record per item)
Prices and quantities change record to record, and I just want the most recent.
This provides me with the most recent entry of each Item (code and date)
SELECT itemCode, MAX(docDate) AS docDate
FROM RDR1
WHERE customerCode= 'TEST001'
GROUP BY ItemCode
Now I need to be able to pull the other pieces of information from those most recent rows, like price and quantity.
I think you want to something like this:
select
* -- or whatever columns you actually want
from
RDR1
inner join
(SELECT itemCode, MAX(docDate) AS docDate
FROM RDR1
WHERE customerCode= 'TEST001'
GROUP BY ItemCode) MD
on MD.docDate = RDR1.docDate
and md.ItemCode = RDR1.ItemCode
SELECT distinct (ItemCode), docDate, Price, Quantity
FROM RDR1
WHERE customerCode= 'TEST001'
ORDER BY docDate DESC
Using ROW_NUMBER:
SELECT *
FROM (
SELECT ROW_NUMBER() OVER (PARTITION BY itemCode ORDER BY docDate DESC) AS RowNumber, *
FROM RDR1
WHERE customerCode = 'TEST001'
) x
WHERE x.RowNumber = 1
ORDER BY x.itemCode
For an overview of multiple customers, add customerCode to the partition:
SELECT ROW_NUMBER() OVER (PARTITION BY customerCode, itemCode ORDER BY docDate DESC) AS RowNumber, *