выбрать по максимальному значению другого столбца - PullRequest
2 голосов
/ 06 ноября 2019

Например, у меня есть таблица с изменениями цен.

TABLE
(
ID INT,
ProductID INT,
ChangeDate DATE,
PriceOld MONEY,
PriceNew MONEY
)

Мне нужно выбрать фактические цены для каждого продукта, т.е. выбрать PriceNew, где ChangeDate - максимум для каждого продукта

Ответы [ 4 ]

3 голосов
/ 06 ноября 2019
SELECT ProductID,PriceNew 
FROM
( 
     SELECT *, ROW_NUMBER() OVER(PARTITION BY ProductID ORDER BY ChangeDate DESC) RN FROM Table1
) X 
WHERE RN = 1
1 голос
/ 06 ноября 2019

Простой метод использует фильтрацию в предложении where:

select t.productid, t.pricenew
from t
where t.changedate = (select max(t2.changedate)
                      from t t2
                      where t2.productid = t.productid
                     );

При индексе (productid, changedate) это часто имеет лучшую производительность, чем другие методы.

1 голос
/ 06 ноября 2019

выберите PriceNew, где ChangeDate является максимальным для каждого продукта

Я бы сформулировал это, используя коррелированный подзапрос для фильтрации. Мне кажется, что это самый простой способ перевести ваши требования, и, как правило, он обеспечивает хорошую производительность по сравнению с другими методами (в частности, оконными функциями или самостоятельным объединением).

select t.*
from mytable t
where ChangeDate = (
    select max(t1.ChangeDate)
    from mytable t1
    where t1.ProductID = t.ProductID
);

Для производительности требуется индекс на(ProductID, ChangeDate).

0 голосов
/ 07 ноября 2019

Функции аналитического окна - ваш лучший выбор - см. Ответ Виньеша Кумара А., который я проголосовал.

Если ваш SQL-код не имеет ROW_NUMBER() или RANK(), вы можете выполнить то же самое с помощью следующегоприсоединяется.

-- this can be problematic if there's multiple prices for the same max ChangeDate 
SELECT
    a.ID
    , a.ProductID
    , a.ChangeDate
    , a.PriceOld
    , a.PriceNew
FROM table a 
    JOIN (SELECT ProductID, max(ChangeDate) max_ChangeDate
            FROM TABLE
            GROUP BY ProductID) b
        ON b.ProductID = a.ProductID
        AND b.max_ChangeDate = a.ChangeDate

-- if IDs are monotonically increasing with time, you can exploit the following. This is better than directly using ChangeDate -- no collisions.        
SELECT
    a.ID
    , a.ProductID
    , a.ChangeDate
    , a.PriceOld
    , a.PriceNew
FROM table a 
    JOIN (SELECT ProductID, max(ID) max_ID
            FROM TABLE
            GROUP BY ProductID) b
        ON b.ProductID = a.ProductID
        AND b.max_ID = a.ID
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...