Выбрать все строки, но только самую последнюю (самую высокую) версию из базы данных
Я хочу получить все строки из БД, где OWNERKEY
1, но только самый высокий DATAVERSION
из DATACONTROLID
,
В приведенном ниже примере у меня есть две строки, где DATACONTROLID
= 1, они имеют 1 и 2 как DATAVERSION
, Я хочу получить самое высокое.
MyDB:
DATAKEY OWNERKEY OWNERTYPE DATAVERSION MALLKEY DATAVALUE DATAVALUETYPE DATACONTROLID DATADATE DATATIME DATASIGN
=========== ============ =========== =========== =========== ========= ============ ============= ========== =========== =========
4 1 2 1 1 1 2 1 2015-11-24 09:55:00:00 ADMIN
3 1 2 2 1 2 2 1 2015-11-23 20:55:00:00 ADMIN
2 1 2 1 1 3 2 2 2015-11-23 15:39:00:00 ADMIN
1 1 2 1 1 4 2 3 2015-11-23 11:29:00:00 ADMIN
Требуемый результат:
DATAKEY OWNERKEY OWNERTYPE DATAVERSION MALLKEY DATAVALUE DATAVALUETYPE DATACONTROLID DATADATE DATATIME DATASIGN
=========== ============ =========== =========== =========== ========= ============ ============= ========== =========== =========
3 1 2 2 1 2 2 1 2015-11-23 20:55:00:00 ADMIN
2 1 2 1 1 3 2 2 2015-11-23 15:39:00:00 ADMIN
1 1 2 1 1 4 2 3 2015-11-23 11:29:00:00 ADMIN
С чего мне начать?
SELECT *
FROM MyDB
WHERE OWNERKEY = 1
Вышеприведенное утверждение является частью obviuos, но как мне исходить из этого?
Я думаю, что я должен использовать MAX(DATAVERSION)
как-то, но на что группировать? И могу ли я использовать оба *
а также MAX
?
3 ответа
Вот простой пример использования GROUP BY
в MSSQL
:
SELECT DATACONTROLID,
MAX(DATAVERSION) AS DATAVERSION, -- Note that 'AS' just gives the column a name in the result set, this isn't required.
OWNERKEY
FROM MyDB
WHERE OWNERKEY = 1
GROUP BY DATACONTROLID, OWNERKEY
Это при условии, что DATACONTROLID
определяет "отдельные" записи и DATAVERSION
это экземпляр записи.
Это сгруппирует DATACONTROLID
столбец и вернуть MAX(DATAVERSION)
для сгруппированного результата. В этом случае, DATACONTROLID = 1
имеет DATAVERSION = 1 and 2
, так что это возвращает 2.
Стоит отметить, что если вы хотите видеть дополнительные столбцы в вашем результате, а они не являются такими агрегатами, какMAX()
, то вам нужно будет добавить их в GROUP BY
пункт - как я сделал здесь с OWNERKEY
колонка. Если вы попытаетесь SELECT OWNERKEY
не имея его в GROUP BY
, вы получите ошибку.
РЕДАКТИРОВАТЬ:
Вот лучший способ добиться того же результата, используя JOIN
:
SELECT *
FROM MyDB mdb
INNER JOIN (
SELECT MAX(DATAVERSION) AS DATAVERSION,
DATACONTROLID
FROM MyDB
WHERE OWNERKEY = 1
GROUP BY DATACONTROLID
) AS mdb2
ON mdb2.DATACONTROLID = mdb.DATACONTROLID
AND mdb2.DATAVERSION = mdb.DATAVERSION
Это делает то же самое GROUP BY
Заявление, которое я показал вам раньше, в таблицу фильтрации. INNER JOIN
часть выбирает MAX(DATAVERSION)
и DATACONTROLID
он принадлежит и возвращает результат как временную таблицу mdb2
,
Эта новая внутренняя таблица вернет следующее:
DATAVERSION DATACONTROLID
2 1
1 2
1 3
Затем мы берем этот результат и получаем все строки (SELECT *)
которые соответствуют этому критерию. Поскольку эта внутренняя таблица не содержит результат для DATAVERSION = 1 where DATACONTROLID = 1
этот ряд отфильтровывается.
И наоборот, если вы хотите видеть только старые версии, а не самые новые, вы можете изменить этот критерий на LEFT OUTER JOIN
и добавить WHERE mdb2.DATAVERSION IS NULL
,
SELECT *
FROM MyDB mdb
LEFT OUTER JOIN (
SELECT MAX(DATAVERSION) AS DATAVERSION,
DATACONTROLID
FROM MyDB
WHERE OWNERKEY = 1
GROUP BY DATACONTROLID
) AS mdb2
ON mdb2.DATACONTROLID = mdb.DATACONTROLID
AND mdb2.DATAVERSION = mdb.DATAVERSION
WHERE mdb2.DATAVERSION IS NULL
Так как мы выбираем MAX(DATAVERSION)
в mdb2
, он будет содержать ноль для строк, которые не соответствуют этим критериям.
Попробуй это:
SELECT *
FROM (SELECT OWNERKEY,DATACONTROLID,DATAVERSION,
rank() over (partition by DATACONTROLID order by DATAVERSION desc) rnk
FROM MyDB WHERE OWNERKEY = 1)
WHERE rnk = 1;
Примечание: я не проверял, но это должно работать
Как насчет
SELECT *
FROM MyDB
WHERE OWNERKEY = 1
and DATAVERSION =
(SELECT max(DATAVERSION)
FROM MyDB
WHERE OWNERKEY = 1)
Это работает в некоторых средах баз данных; Я надеюсь, что ваш! Я узнал об этом из "Введение в SQL, освоение языка реляционных баз данных" Рика Ф. ван дер Ланса. Довольно легко читать.