Условие
Таблицы:
Sales(sale_id, product_id, year, quantity, price)Product(product_id, product_name)— справочник.
Для каждого продукта верните строки продаж в год его первой продажи: product_id, first_year, quantity, price. Может быть несколько строк за один (первый) год.
Решение
Через MIN(year) на продукт
WITH first_year AS (
SELECT product_id, MIN(year) AS first_year
FROM Sales
GROUP BY product_id
)
SELECT s.product_id, s.year AS first_year, s.quantity, s.price
FROM Sales s
JOIN first_year fy
ON fy.product_id = s.product_id
AND fy.first_year = s.year;Через оконную функцию
SELECT product_id, year AS first_year, quantity, price
FROM (
SELECT
s.*,
MIN(year) OVER (PARTITION BY product_id) AS min_year
FROM Sales s
) t
WHERE year = min_year;MIN OVER без ROWS даёт минимум по всему партишену — экономит шаги.
Подводные камни
RANK() OVER (ORDER BY year) = 1. Тоже работает, но не сразу очевидно, что если у продукта 3 строки за 2018 (минимум) — все три попадут (это правильно, в отличие отROW_NUMBER = 1).- Дубли строк в Sales. В задаче PK на
sale_id, дублей нет. В реальности — DISTINCT по нужным полям, иначе можно посчитать дважды. - Год как INT vs DATE. Здесь
year INT—MINсразу даёт число. Если быsale_date DATE, использовали быEXTRACT(YEAR ...).
Эталонный ответ
MIN(year) OVER (PARTITION BY product_id) или JOIN с MIN(year) GROUP BY product_id, фильтр year = first_year. Все строки минимального года — в выходе.