I have a table with price lists that specifies the price of an item in a country for a specific time period. The issue with my table is, that there are overlapping price lists for the same item in the same country. What I wish, is to select the overlapping price list with the latest valid from date. Looking at the picture below the highlighted rows would be the desired end-result out of the 7 example rows:
Data sample:
CREATE TABLE #PriceList
(
[Country] VARCHAR(15),
[Price list] VARCHAR(25),
[Item number] INTEGER,
[Price] DECIMAL(10, 2),
[Valid from] INTEGER,
[Valid to] INTEGER
);
INSERT INTO #PriceList
(
Country,
[Price list],
[Item number],
Price,
[Valid from],
[Valid to]
)
VALUES
('United Kingdom', 'Price list Tech', 33333, 20.50, 20200101, 20201231),
('United Kingdom', 'Price list Tech', 33333, 20.50, 20200102, 20201231),
('Germany', 'Price list stuff', 44444, 15.50, 20200102, 20201231),
('Germany', 'Price list stuff', 44444, 15.50, 20200101, 20200630),
('USA', 'Price list textile new', 55555, 32.25, 20200102, 20201231),
('USA', 'Price list textile', 55555, 32.50, 20200101, 20200630),
('Germany', 'Price list stuff', 44444, 15.50, 20210101, 20210630);
What I have tried:
SELECT Country,
[Price list],
[Item number],
[Price],
[Valid from],
[Valid to]
FROM(
SELECT Country,
[Price list],
[Item number],
[Price],
[Valid from],
[Valid to],
ROW_NUMBER() OVER (PARTITION BY a.Country,
a.[Item number],
a.[Valid to]
ORDER BY a.[Valid from] DESC
) AS rn
FROM #PriceList a
) b
WHERE b.rn = 1
OUTPUT:
As you can see there are still overlapping price lists.
If I remove "Valid to" in the partition by clause then row_number will eliminate too many price lists. As you can see it eliminated two of Germany's price lists when it should only have eliminated the overlapping one. Without "Valid to", it strictly just checks for the latest "Valid from" date.
SELECT Country,
[Price list],
[Item number],
[Price],
[Valid from],
[Valid to]
FROM(
SELECT Country,
[Price list],
[Item number],
[Price],
[Valid from],
[Valid to],
ROW_NUMBER() OVER (PARTITION BY a.Country,
a.[Item number]
ORDER BY a.[Valid from] DESC
) AS rn
FROM #PriceList a
) b
WHERE b.rn = 1
All help, tips and ideas are highly appreciated!
try this simplified query with [price list] / Country / Item / year(valid from)
the windowed function
FIRST_VALUE()
can do the trick along withdistinct
results: