select from table1 depend on newest date in table 2 [duplicate]
I have 2 tables like above
table1 = items => id, name
table 2 = item_price => item_id, date,price
I need to
select items.name from items
INNER JOIN item_price ON items.id = item_price2.item_id
where item_price.date is last date
items
id name
1 item name 1
2 item name 2
3 item name 3
item_price
item_id date price
1 2022-01-13 5
2 2022-01-10 7
1 2022-01-10 4
1 2022-01-09 9
I need build query to get this result
item name price
item name 1 5
item name 2 7
thanks a lot
Solution 1:
This can be solved by selecting the last row using the ROW_NUMBER windowed partition function.
WITH last_item_price (item_id, price, reverse_order)
AS
(SELECT item_id
, price
, ROW_NUMBER() OVER
(PARTITION BY item_id
ORDER BY date DESC) AS reverse_order
FROM item_price)
SELECT i.name
, p.price
FROM items i
JOIN last_item_price p
ON i.item_id = p.item_id
AND p.reverse_order = 1;
Unless the primary key of item_price is defined as the composite key for item_id and date, there is a risk you will have more than one possible price. For instance, if the price changes three times on a single day, then how do you know which is the correct value? I would recommend using a DATETIME or DATETIME2 field to help pick the correct price in that scenario. Alternatively, you can define the primary key as the composite of the two fields and only allow a single price each day.
Another way to avoid the duplication issue is to add an auto-incrementing identity column. This will not be useful for joins and I still strongly recommend using a composite key for the item_id and date fields, but it is a valid alternative. In that case, you can modify the partition function's ORDER BY clause to:
ORDER BY date DESC, item_price_id DESC
In general, I would not recommend naming a field date. Since SQL Server has a data type called DATE, this can cause issues with linters. In some cases, you may be required to use brackets so the field is [date] to disambiguate your intent. A better name is probably price_date or price_change_date.