Нужно выбрать строки из таблицы со столбцом версии, которые соответствуют последней версии - PullRequest
0 голосов
/ 14 января 2012

Каков наилучший способ сделать это в SQL (Sybase SQL, если различия имеют значение):

Таблица: (с некоторыми данными выборки)

| id | value1 | value2 | version |
==================================
| 1  | A11    | B11    | 1       | 
| 1  | A12    | B12    | 2       | 
| 2  | A21    | B21    | 1       | 
| 3  | A32    | B32    | 2       | 

Unique key: (id, version). Index: (id, version)

Размер набора данных: ~ 100 тыс. Строк в таблице, с предложением типичного запроса where, ограничивающим результаты 10-100 идентификаторами и номерами версий, равными 1,2 или иногда 3.

Что мне нужно сделать: для каждого идентификатора, получить строку с самой высокой версией для этого идентификатора

| id | value1 | value2 | version |
==================================
| 1  | A12    | B12    | 2       | <---- Chosen since 2>1 for id=1
| 2  | A21    | B21    | 1       | 
| 3  | A32    | B32    | 2       | 

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

SELECT  id, value1, value2
FROM    T   'T1'
WHERE   id in (1, 2, 3, ... 10)  -- Obviously a fake sample clause
 AND    version = (SELECT MAX(version) FROM T 'T2' 
                   WHERE T1.id=T2.id
                    AND  id in (1, 2, 3, ... 10)
                  )

Вопрос: Это лучший подход?

«Лучший» здесь означает:

  1. «лучший результат в среднем» (с учетом размера набора данных, типичного размера запроса и индексов, показанных выше).

  2. Для подходов с аналогичной производительностью наиболее элегантный код. Это очевидно для наблюдателя, но если вы можете показать, что код является более расширяемым / обслуживаемым, это явный признак элегантного кода.

Ответы [ 2 ]

2 голосов
/ 14 января 2012
SELECT *
FROM (
   SELECT id, 
          value1, 
          value2, 
          version,
          max(version) over (partition by id) as max_version
    FROM T
    WHERE id IN (1, 2, 3, ... 10)
) t2
WHERE version = max_version

В зависимости от вашей СУБД (особенно оптимизатора) и индексов это может быть быстрее, чем для подвыбора, так как требуется только одно сканирование таблицы.

0 голосов
/ 14 января 2012

Я думаю, что использование JOIN вместо подзапроса делает его более читабельным:

SELECT  id, value1, value2
FROM    T   'T1'
INNER JOIN (
  SELECT id,MAX(version) as version 
  FROM T 
  WHERE id IN (...)
  GROUP BY id) T2
 ON (T1.id = T2.id AND T1.version=T2.version)
WHERE   T1.id in (1, 2, 3, ... 10)  

Это не должно вызывать каких-либо потерь производительности / преимуществ по сравнению с исходным запросом.

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