Соедините две таблицы, используйте только последнее значение правой таблицы - PullRequest
2 голосов
/ 29 февраля 2012

Я пытаюсь объединить 2 таблицы, но объединить только последнюю запись в группе записей.

Левая таблица:

Часть

  • Part.PartNum

Правильный стол:

Материал

  • Material.Partnum
  • Material.Formula
  • Material.RevisionNum

Номер редакции начинается с "A" и увеличивается.

Я хотел бы объединить 2 таблицы:PartNum, но только с последней записью из правой таблицы.Я видел другие примеры на SO, но с трудом складывал все это вместе.

Edit:

Я обнаружил, что первый номер ревизии - "New", затем он увеличивает A, B... Это никогда не будет больше, чем одна или две ревизии, поэтому я не беспокоюсь о том, чтобы пересмотреть последовательность.Но как выбрать последний вариант с номером «Новый», который будет номером первой ревизии?

Ответы [ 3 ]

5 голосов
/ 29 февраля 2012

Если SQL Server 2005 +

;WITH m AS 
(
   SELECT Partnum, Formula, RevisionNum,
     rn = ROW_NUMBER() OVER (PARTITION BY PartNum ORDER BY 
       CASE WHEN RevisionNum ='New' THEN 1 ELSE 2 END)
     FROM dbo.Material
)
SELECT p.PartNum, m.Formula, m.RevisionNum
FROM dbo.Parts AS p
INNER JOIN m ON p.PartNum = m.PartNum
WHERE m.rn = 1;

Хотя любопытно, что вы делаете, когда существует более 26 ревизий (например, что следует за Z)?

4 голосов
/ 29 февраля 2012

Общий SQL-оператор, который запустил бы это:

select P.PartNum, M.Formula, M.RevisionNum
from Parts P
join Material M on P.PartNum = M.PartNum
where M.RevisionNum = (select max(M2.RevisionNum) from Material M2
                       where M2.PartNum = P.PartNum);

Повторение приведенных выше предостережений о том, что происходит после пересмотра № 26. Макс (RevisionNum) может сломаться в зависимости от того, что происходит после # 26.


EDIT:

Если последовательность RevisionNum всегда начинается с NEW и затем продолжается, A, B, C и т. Д., То max () необходимо заменить на что-то более сложное (и грязное):

select P.PartNum, M.RevisionNum
from Parts P
join Material M on P.PartNum = M.PartNum
where (
      (select count(*) from Material M2 
              where M2.PartNum = P.PartNum) > 1
      and M.RevisionNum = (select max(M3.RevisionNum) from Material M3
                   where M3.PartNum = P.PartNum and M3.RevisionNum <> 'NEW')
      )
      or ( 
      (select count(*) from Material M4
              where M4.PartNum = P.PartNum) = 1
       and M.RevisionNum = 'NEW'
      )

Должен быть лучший способ сделать это. Это работает, хотя - придется подумать о более быстром решении.

SQL Fiddle: http://sqlfiddle.com/#!3/70c19/3

1 голос
/ 29 февраля 2012

SQL Server 2005+, а также:

Обновлено для обработки изменяющихся требований OP

SELECT P.PartNum,
       M.Formula,
       M.RevisionNum
FROM Part AS P
CROSS APPLY (
    SELECT TOP 1 *
    FROM Material AS M
    WHERE M.Partnum = P.PartNum
    ORDER BY CASE WHEN RevisionNum ='New' THEN 2 ELSE 1 END,
             M.RevisionNum DESC
) AS M
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...