ВЫБЕРИТЕ UnitCost на MAX (OrderDate) из другой таблицы

У нас есть система ERP с таблицей заголовка заказа на покупку (POHeader) и таблицей строк заказа на покупку (PODetail). Существуют сотни тысяч POLines, многие детали которых неоднократно приобретались в течение нескольких лет. Мне нужно найти UnitCost каждой детали, купленной с момента последней покупки (max(OrderDate) заказа на поставку).

Я играл с номером заказа SQL MAX(DATE), для которого у меня почти одинаковый требования. Если мы посмотрим на код решения в этом потоке:

SELECT t.ClientId, t.MaxDate, o.OrderNumber
FROM (SELECT ClientId, MAX(Date) as MaxDate
          FROM dbo.tblOrders
          GROUP BY ClientId) t
    INNER JOIN dbo.tblOrders o
        ON t.ClientId = o.ClientId
            AND t.MaxDate = o.Date

Мои потребности идентичны, где мой номер детали — его ClientId, а моя UnitCost — его OrderNumber. Быстрая замена даст мне что-то вроде этого:

SELECT t.PartNum, t.MaxDate, o.UnitCost
FROM (SELECT PartNum, MAX(OrderDate) as MaxDate
          FROM POdetail
          GROUP BY PartNum) t
    INNER JOIN POdetail o
        ON t.PartNum = o.PartNum
            AND t.MaxDate = o.Date

Проблема в том, что даты заказов на покупку хранятся на уровне заголовка, а в подробных данных даты отсутствуют. Я должен LEFT JOIN в max(OrderDate) из таблицы POHeader, и вот где у меня проблемы.

Я пытался составить OrderDate из таблицы POHeader, но мой код неверен. Вот где я остановился. Может ли кто-нибудь помочь мне с этим утверждением, пожалуйста?:

SELECT d.PartNum, h.MaxDate, d.UnitCost
    FROM 
    PODetail d
    Left Join POHeader h ON 
    (SELECT PONum, MAX(OrderDate) as MaxDate
              FROM POHeader
              GROUP BY PONum) t
        INNER JOIN POHeader o
            ON t.PONum = o.PONum
                AND t.MaxDate = o.OrderDate

Вот какие-то дурацкие данные...

create table POHeader (POnum int, OrderDate date);
insert into POHeader (PONum, OrderDate) values (12508, '05/13/2010');
insert into POHeader (PONum, OrderDate) values (12690, '06/04/2010');
insert into POHeader (PONum, OrderDate) values (12847, '09/08/2010');
create table PODetail (PONum int, PartNum varchar(15), Descript varchar(60), UnitCost numeric(10,2));
insert into PODetail (PONum, PartNum, Descript, UnitCost) values (12508, 'X37-BC055', 'PIPE, Titanium (MIL-T-9046), 3"OD x 8FT x .0125"', 6647.18);
insert into PODetail (PONum, PartNum, Descript, UnitCost) values (12690, 'X37-BC055', 'PIPE, Titanium (MIL-T-9046), 3"OD x 8FT x .0125"', 6651.90);
insert into PODetail (PONum, PartNum, Descript, UnitCost) values (12847, 'X37-BC055', 'PIPE, Titanium (MIL-T-9046), 3"OD x 8FT x .0125"', 6713.65);
insert into PODetail (PONum, PartNum, Descript, UnitCost) values (12690, 'N76-18824-ABN', 'COLLAR, Titanium (AMS 4902), 3"ID Flange', 564.13);
insert into PODetail (PONum, PartNum, Descript, UnitCost) values (12847, 'N76-18824-ABN', 'COLLAR, Titanium (AMS 4902), 3"ID Flange', 571.26);

Вы можете видеть в данных истории, что я купил 8-футовую трубу три раза и муфту дважды. Я пытаюсь добиться такого результата - в последний раз, когда я купил каждую часть:

PartNum        Max Date   Last Price
-------------  ---------- ----------
X37-BC055      9/08/2010     6713.65
N76-18824-ABN  6/04/2010      571.26

Спасибо за помощь, JM


person John Joseph    schedule 06.08.2019    source источник
comment
Я довольно потерян от того, что вы пытаетесь сделать.   -  person Gordon Linoff    schedule 06.08.2019
comment
@GordonLinoff Мне нужна ПОСЛЕДНЯЯ цена всех деталей в PODetail с момента последней покупки каждой детали. За исключением того, что ДАТА каждой покупки указана в POHHeader, а не в деталях.   -  person John Joseph    schedule 06.08.2019
comment
Какую базу данных вы используете? Отметьте свой вопрос   -  person forpas    schedule 06.08.2019
comment
Прогресс 10 с универсальным драйвером ODBC для OpenEdge. Я использую WinSQL Lite   -  person John Joseph    schedule 06.08.2019


Ответы (2)


Получите все последние даты, а затем присоединитесь к таблицам:

select d.partnum PartNum, c.orderdate MaxDate, d.unitcost LastPrice
from podetail d 
inner join poheader h on h.ponum = d.ponum
inner join (
  select d.partnum, max(h.orderdate) orderdate
  from podetail d inner join poheader h
  on h.ponum = d.ponum
  group by d.partnum
) c on c.partnum = d.partnum and c.orderdate = h.orderdate
person forpas    schedule 06.08.2019
comment
Извините за форпас. Я увидел ваш запрос тега и добавил Progress. Эта база данных не поддерживает CTE. Можно ли пойти по старой школе, просто присоединившись? - person John Joseph; 06.08.2019

используйте row_number(), которые поддерживают max dbms

   select * from
    (select ph.*,PartNum,UnitCost as lstPrice,row_number() over(partition by PartNum order by OrderDate desc) rn
   from POHeader ph INNER JOIN POdetail po
    ON ph.PONum = po.PONum
    ) a where a.rn=1
person Zaynul Abadin Tuhin    schedule 06.08.2019
comment
мой редактор SQL показывает синтаксическую ошибку рядом с POHeader в вашей третьей строке. Оператор не запустится. - person John Joseph; 06.08.2019
comment
@JohnJoseph я пропустил, чтобы написать в запросе - person Zaynul Abadin Tuhin; 06.08.2019
comment
Также ВКЛ должно быть ph.PONum = po.PONum - person HereGoes; 06.08.2019
comment
Вот и все! Спасибо. Возможно ли без row_number над разделом? Моя база данных не SQL Server, это Progress Open Edge с универсальным драйвером ODBC. Я использую WinSQL Lite. - person John Joseph; 06.08.2019