T-SQL-запрос: получить последние подходы строки - PullRequest
4 голосов
/ 08 сентября 2010

На основе следующей таблицы

Table_A

ID   Rev  Description
-----------------------------------
1    1    Some text.
1    2    Some text. Adding more.
1    3    Some text. Ading more & more.

Выше будет добавляться новая строка, когда пользователь обновляет описание.

Я хочу взять строку с MAX (Rev) [т.е.последнее описание.

Чтобы получить это, я делаю следующее:

;with AllDescriptions As
(
 select 
        ID
        , Rev
        , Description 
        , ROW_NUMBER() over (partition by ID order by Rev desc) as RowNum
        from Table_A
        Where ID = 1
)
select ID, Rev, Description from AllDescription
where RowNum = 1

Недавно я увидел другой подход к получению того же результата

select b.* from 
(
 select ID, MAX(Rev) as MaxRev 
 from Table_A 
 where ID = 1
 group by ID
) as a
inner join 
(
 select ID, Rev, Description from Table_A where ID = 1
) as b
on a.ID = b.ID and a.MaxRev = b.Rev

С точки зрения обучения я хочузнаете, какой из двух вышеперечисленных подходов лучше?Или если есть еще лучший способ сделать то же самое?

Ответы [ 3 ]

1 голос
/ 08 сентября 2010

Второй подход похож на подход SQL Server 2000 до введения Row_Number(). Это проблема Greatest-n-per-group .

Чтобы оценить их, вам нужно посмотреть на планы выполнения и статистику ввода / вывода, набрав SET STATISTICS IO ON

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

 select TOP 1
        ID
        , Rev
        , Description 
        from Table_A
        Where ID = 1
ORDER BY Rev desc
1 голос
/ 08 сентября 2010

Если у вас есть родительская таблица, в которой каждый идентификатор указан только один раз, это иногда может превзойти другие стратегии, включая решение row_number:

SELECT
   X.*
FROM
   ParentTable P
   CROSS APPLY (
      SELECT TOP 1 *
      FROM Table_A A
      WHERE P.ID = A.ID
      ORDER BY A.Rev DESC
   ) X

И сумасшедший, запатентованный (просто шучу) магический запрос с одним сканированием, который часто может превзойти и другие методы:

SELECT
   ID,
   Rev = Convert(int, Substring(Packed, 1, 4)),
   Description = Convert(varchar(100), Substring(Packed, 5, 100))
FROM
   (
      SELECT
         ID,
         Packed = Max(Convert(binary(4), Rev) + Convert(varbinary(100), Description))
      FROM Table_A
      GROUP BY ID
   ) X

Примечание: этот последний метод не рекомендуется, но интересно моделировать первые / последние агрегаты в MS Access.

0 голосов
/ 08 сентября 2010

Я предпочел бы предпочесть первый подход - с точки зрения читабельности, когда вы освоитесь с синтаксисом ROW_NUMBER () OVER ..., тогда он станет несколько более читабельным. С точки зрения производительности, я был бы удивлен, если бы между этими двумя было много различий - если бы тогда было то, я ожидал бы, что второй будет работать хуже - но я должен исправить это!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...