2011-12-25 1 views
2

У меня есть эта таблицаНайти максимальную строку и ее значение в SQL Server 2000

ID Level Value 
1  1  10 
1  2  20 
1  3  15 
1  4  18 
2  2  12 
2  1  20 
3  1  50 
3  2  80 

Я хочу, чтобы найти уровень максимального для каждого идентификатора и значение этого максимального ряда, Результат:

ID Level Value 
1  4  18 
2  2  12 
3  2  80 

Я не хочу использовать вложенный «Select», потому что моя таблица слишком большая и вложенная выбирает замедлить мой запрос Спасибо за любую помощь

ответ

0

Вы можете сделать это с помощью самоподключения и теста для null.

SELECT T.* 
FROM T 
LEFT OUTER JOIN T AS T2 
ON T2.ID = T.ID AND T2.[Level] > T.[Level] 
WHERE T2.ID IS NULL 
6

Не проиндексирован в SQL Server 2000, но при условии, что Level и Value являются целыми положительными целями, которые должны выполняться без использования вложенных SELECT.

SELECT ID, 
     MAX(Level) AS Level, 
     Max(Level * Cast(10000000000 AS NUMERIC(38)) + Value) 
               % 10000000000 AS Value 
FROM T 
GROUP BY ID 

Или вариант, который отлично справляется с отрицательными значениями

SELECT ID, 
     Max(Level) AS Level, 
     Cast(Substring(Max(CASE 
          WHEN Level < 0 THEN 0x00 
          ELSE 0x01 
          END + Cast(Level AS BINARY(4)) + 
           Cast(Value AS BINARY(4))), 6, 4) AS INT) AS Value 
FROM T 
GROUP BY ID 
+0

+1 Очень интересная идея. Не могли бы вы просто использовать 'max (Level)' для второго столбца? – DavidEG

+0

@DavidEG - Хорошая точка! Изменится. –

+2

Если кто-то задается вопросом, как работает эта «магия», столбец уровня увеличивается и добавляется в столбец значений. Это перемещает значение вместе с уровнем, когда применяется max. Затем значение увеличенного уровня удаляется, оставляя значение. –

0

Чтобы обеспечить альтернативу:

select T.* from 
(select ID, MAX(Level) as M_Level from T group by ID) Q, T 
where Q.ID = T.ID and Q.M_Level = T.Level 

Я знаю, что вы не хотите вложенный выбор, но это может быть удобно в разные ситуации. Я тестировал его с помощью SQL Profiler с несколькими миллионами строк, разница в производительности допустима.