You will need to use a correlated subquery to get the price as of a given date:
SELECT
price.drug
,price.date
,price.new_price
FROM
DrugPrice price
WHERE
price.Drug = 'acetaminophen'
AND price.new_price =
(
SELECT
MAX(date)
FROM
DrugPrice
WHERE
Drug = price.Drug
AND date <= '2020-02-01'
)
You will need a unique B-tree index on (Drug,Date)
for that query to return consistent results in a reasonable amount of time.
For the ten cheapest type of query you can do something along the lines of:
SELECT
drug
,date
,new_price
,price_order
FROM
(
SELECT
price.drug
,price.date
,price.new_price
,ROW_NUMBER() OVER (PARTITION BY 1 ORDER BY price.new_price, price.drug) AS price_order
FROM
DrugPrice price
WHERE
price.Drug = 'acetaminophen'
AND price.new_price =
(
SELECT
MAX(date)
FROM
DrugPrice
WHERE
Drug = price.Drug
AND date <= '2020-02-01'
)
) x
WHERE
price_order <= 10
This is going to require scanning the whole table, then ordering the rows, which can be expensive. If you can keep the underlying table small then this might not take too long and there may be no need to go further. But if the requirement is to return that data right away, you can create a table like this and run an update to check for changed records each day:
CREATE TABLE PriceSummary
(
RankTypeCd CHAR(1) NOT NULL --Ascending/descending/other metrics probably make this a FK to a reference table
,DrugRank TINYINT NOT NULL --Don't need to rank everything, just maybe top 100
,AsOfDt DATE NOT NULL
,Drug <whatever> NOT NULL
,CONSTRAINT FK_PriceSummary_Summarizes_Drug FOREIGN KEY (Drug) REFERENCES <Drug Table> (Drug)
,CONSTRAINT PK_PriceSummary PRIMARY KEY (RankTypeCd, DrunkRank, AsOfDt)
)
Then if you wanted to get the least expensive drugs (let's call that RankTypeCd = 'A'
for ascending) you could:
SELECT
PriceSummary.Drug
,PriceSummary.DrugRank
FROM
PriceSummary PriceSummary
WHERE
PriceSummary.RankTypeCd = 'A'
AND PriceSummary.DrugRank <= 10
AND PriceSummary.AsOfDt =
(
SELECT
MAX(AsOfDt)
FROM
PriceSummary
WHERE
RankTypeCd = PriceSummary.RankTypeCd
AND DrugRank = PriceSummary.DrugRank
AND AsOfDt <= '2020-02-01'
)