Возврат группы самых последних записей по 2 полям идентификатора - PullRequest
0 голосов
/ 14 октября 2019

Мне нужно отобразить текущий статус детали («утвержден» или «не утвержден»). Я настраиваю таблицу состояния как MaterialNo, ToolID, Status, Asofdate

идея в том, что у меня может бытьнесколько инструментов одобрены и несколько не утверждены. Я хочу видеть последний статус каждого инструмента, но не хочу видеть исторический статус.

пытался использовать MAX (Asofdate) и группировать по MaterialNo, ToolID и Status, но он возвращает всю историю состояний для каждого.

SELECT MaterialNo, ToolID, PPAPStatus, MAX(Asof) as "AsOf"
  FROM [MfgDataCollector].[dbo].[PPAPStatus]
  Group By MaterialNo, ToolID, PPAPStatus

Таблица состояния содержит эти данные:

MaterialNo  ToolID  Status          Asofdate
52748677    1       Not approved 2019-10-10
52748677    1       approved    2019-10-13
52748677    2       approved    2019-10-14

Я хочу увидеть:

MaterialNo  ToolID  Status         Asofdate
52748677    1       approved    2019-10-13
52748677    2       approved    2019-10-14

Ответы [ 4 ]

4 голосов
/ 14 октября 2019

Одним из решений, которое обычно имеет очень хорошую производительность, является коррелированный подзапрос:

select p.*
from [MfgDataCollector].[dbo].[PPAPStatus] p
where p.asof = (select max(p2.asof)
                from [MfgDataCollector].[dbo].[PPAPStatus] p2
                where p2.MaterialNo = p.MaterialNo and
                      p2.ToolID = p.ToolID
               );

Для оптимальной производительности вам нужен индекс для (MaterialNo, ToolID, asof).

3 голосов
/ 14 октября 2019

Мне нравится использовать ROW_NUMBER с трюком TOP 1 WITH TIES:

SELECT TOP 1 WITH TIES MaterialNo, ToolID, Status, Asofdate
FROM [MfgDataCollector].[dbo].[PPAPStatus]
ORDER BY ROW_NUMBER() OVER (PARTITION BY MaterialNo, ToolID ORDER BY Asofdate DESC);
2 голосов
/ 14 октября 2019

Лучшим вариантом будет row_number ()

   Select MaterialNo, ToolID, 
    PPAPStatus,AsofNow from (Select 
     MaterialNo, ToolID, 
      PPAPStatus,AsofNow, row_number() 
       over 
           (partition 
         by MaterialNo, ToolId, PPAStatus 
              order by 
            AsofNow desc) rn
       FROM [MfgDataCollector].[dbo]. 
       [PPAPStatus]
      ) t where t.rn=1
0 голосов
/ 15 октября 2019

Наилучшим вариантом будет ROW_NUMBER () без более сложной логики с простым разделением по полям.

Ниже приведен запрос по запросу.

;WITH CTE AS
(
SELECT *, 
ROW_NUMBER() OVER (PARTITION BY MaterialNo,ToolID ORDER BY Asofdate DESC) AS ROWNM
FROM [MfgDataCollector].[dbo].[PPAPStatus]
)
SELECT * FROM CTE WHERE ROWNM=1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...