I don't know how to format?!, but I believe it's easy to understand. I have the following table, lets call it "sales"
|Item| |Price| |PriceDate|
ItemA 801.36 09/23/2011
ItemA 800.64 09/23/2011
ItemA 803.55 09/22/2011
ItemB 4701.36 09/22/2011
ItemB 1101.36 09/22/2011
ItemB 4801.36 09/20/2011
ItemB 401.36 09/22/2011
ItemC 9601.36 09/21/2011
ItemC 201.36 09/19/2011
ItemC 301.36 09/17/2011
I'm given a date and I need to retrieve the records with the closest date, and only those, for example, if 09/24/2011 is the input, the output should be only the records from the 23rd for item A, 22nd for itemB, and 21st for itemC.
Using SQL Server 2012.
One way to go about it is to calculate the difference between the row's data and the given date by using datediff
, assign a rank
to each row accordingly and filter by it.
Here I'm using ?
as a placeholder for the required date, just switch it with the correct syntax of the language you're using:
SELECT item, price, pricedate
FROM (SELECT item, price, pricedate,
RANK() OVER (PARTITION BY item
ORDER BY ABS(DATEDIFF(day, pricedate, ?))) AS rk
FROM salse) t
WHERE rk = 1
DECLARE @theTable TABLE (Item VARCHAR(10), price DECIMAL(10,2), priceDate DATE)
INSERT @theTable ( Item, price, priceDate )
VALUES
('ItemA',801.36,'2011-09-23'),
('ItemA',800.64,'2011-09-23'),
('ItemA',803.55,'2011-09-22'),
('ItemB',4701.36,'2011-09-22'),
('ItemB',1101.36,'2011-09-22'),
('ItemB',4801.36,'2011-09-20'),
('ItemB',401.36,'2011-09-22'),
('ItemC',9601.36,'2011-09-21'),
('ItemC',201.36,'2011-09-19'),
('ItemC',301.36,'2011-09-17')
DECLARE @inputDate DATE
SET @inputDate = '2011-09-24'
SELECT X.Item, X.price, X.priceDate FROM (
SELECT TT.Item, TT.price, TT.priceDate,
RANK() OVER (PARTITION BY [Item]
ORDER BY ABS(DATEDIFF(DAY, @inputDate, TT.priceDate))) AS RN
FROM @theTable TT
) AS X
WHERE RN = 1
(10 row(s) affected) Item price priceDate ---------- --------------------------------------- ---------- ItemA 801.36 2011-09-23 ItemA 800.64 2011-09-23 ItemB 4701.36 2011-09-22 ItemB 1101.36 2011-09-22 ItemB 401.36 2011-09-22 ItemC 9601.36 2011-09-21
i have the same problem but i found that i can solve it on front end by easier way
/*back end*/
/*(DistinctItem) select distinct Item from sales*/
/*(saleRecords) select * from sales order by PriceDate desc*/
/*front end*/
for(var j = 0; j < DistinctItem.length;j++){
for(var i = 0; i < saleRecords.length;i++){
if(DistinctItem[j].Item==saleRecords[i].Item){
if(anyDate>saleRecords[i].PriceDate){
use saleRecords[i];
break;
}
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.