Как я могу выбрать только последнюю строку в запросе объединения

#sql #sql-server

#sql #sql-сервер

Вопрос:

Я очень новичок в сложных SQL-запросах, поэтому, пожалуйста, извините меня, если эту проблему можно легко решить. У меня есть таблица с VocabCards, в которой важным столбцом является только идентификатор. Затем у меня есть таблица VocabCardEvent, в которой сохраняются события, происходящие с этой VocabCard. Событие, которое я должен получить в этом варианте использования, — это изменение сложности. Важными столбцами являются идентификатор (varchar), дата создания (DateTime) и тип (int), который сохраняет изменение сложности. Идентификатор состоит из 16 символов: 8 из флэш-карты и 8 уникальных.

Теперь к моему вопросу: мне нужно получить все VocabCards и соответствующий новейший VocabCardEvent. Как я могу этого добиться?

Что я сделал до сих пор:

  • Подзапрос (проблема: я не могу передать текущий идентификатор флэш-карты в подзапрос, поэтому я всегда получаю первый VocabCardEvent)
  • Объединить с Top(1) и упорядочить по CreatedDate (проблема: я получаю только одну VocabCard)
  • Объединение с помощью подзапроса (проблема: я получаю все VocabCardEvents, поэтому у меня есть одна VocabCard несколько раз)

Я надеюсь, что с этим объяснением все в порядке. Спасибо, что попытались помочь заранее.

Ответ №1:

В SQL Server APPLY это очень хороший подход:

 select vc.*, vce.*
from VocabCards vc outer apply
     (select top (1) vce.*
      from VocabCardEvents vce
      where vce.vocabcardid = vc.id
      order by vce.createddate desc
     ) vce;
 

Ответ №2:

Вы можете использовать аналитическую функцию row_number следующим образом:

 Select * from
(select vc.*, vce.*,
       Row_number() over (partition by vc.id order by vce.createddate desc) as rn
from VocabCards vc 
Join VocabCardEvents vce
  On vce.vocabcardid = vc.id) t
Where rn = 1