stackoverflow.com/questions/50467068/...

вел некоторые поиски, и, похоже, не могу получить результаты, которые я ищу. По сути, в нашей компании действуют четыре разные системы управления, и я нахожусь в процессе регулярного объединения всех данных из каждой системы. Моя цель - обновлять данные каждый час в центральной базе данных. Вот пример набора данных, с которым я работаю:

COMPUTERNAME | SERIALNUMBER | USERNAME | LASTIP | LASTUPDATE | SOURCE
TEST1 | 1111 | BOB | 1.1.1.1 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST1 | 1111 | BOB | 1.1.1.1 | 1/18/2011 01:00:00 | MGMT_SYSTEM_2
TEST1 | 1111 | PETER | 1.1.1.11 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST2 | 2222 | GEORGE | 1.1.1.2 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST3 | 3333 | TOM | 1.1.1.3 | 1/19/2011 01:00:00 | MGMT_SYSTEM_2
TEST4 | 4444 | MIKE   | 1.1.1.4 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST4 | 4444 | MIKE   | 1.1.1.41 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST5 | 5555 | SUSIE  | 1.1.1.5 | 1/19/2011 01:00:00 | MGMT_SYSTEM_1

Поэтому я хочу запросить эту основную таблицу и получить только последнюю запись (на основе LASTUPDATE), чтобы получить последнюю информацию об этой системе. Проблема в том, что в каждой базе данных может быть одна система, но, конечно, у них никогда не будет одинакового точного времени обновления.

Я ожидаю получить что-то вроде этого:

TEST1 | 1111 | PETER | 1.1.1.11 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST2 | 2222 | GEORGE | 1.1.1.2 | 1/17/2011 01:00:00 | MGMT_SYSTEM_1
TEST3 | 3333 | TOM | 1.1.1.3 | 1/19/2011 01:00:00 | MGMT_SYSTEM_2
TEST4 | 4444 | MIKE   | 1.1.1.41 | 1/19/2011 01:00:00 | MGMT_SYSTEM_3
TEST5 | 5555 | SUSIE  | 1.1.1.5 | 1/19/2011 01:00:00 | MGMT_SYSTEM_1

Я попытался использовать функцию MAX, но с этим я могу получить только один столбец. И я не могу использовать это в подзапросе, потому что у меня нет уникального поля идентификатора, которое дало бы мне последнюю обновленную запись. Одной из систем является база данных MySQL, и функция MAX в MySQL фактически будет работать так, как мне нужно, только возвращая одну запись на один GROUP BY, но она не работает в SQL Server.

Я думаю, что мне нужно использовать MAX и LEFT JOIN, но мои попытки пока не увенчались успехом.

Ваша помощь будет принята с благодарностью. Последние 3-4 часа я ломал голову, пытаясь получить рабочий запрос. Эта основная таблица расположена на сервере SQL Server 2005.

Спасибо!

Ответы на вопрос(2)

ный подзапрос:

select t.*
from t
where t.lastupdate = (select max(t2.lastupdate)
                      from t t2
                      where t2.computername = t.computername
                     );

В частности, это может использовать индекс(computername, lastupdate), Концептуально, причина это быстрее, чемrow_number() потому что этот запрос просто отфильтровывает строки, которые не совпадают.row_number() Версия должна быть привязана к номеру строки для всех строк, прежде чем она будет отфильтрована - это дополнительная обработка данных.

 Askar Ibragimov21 мая 2018 г., 10:10
Не могли бы вы прокомментировать, что я буду делать, если мне нужно, чтобы «внутреннее» выделение содержало строки с максимальным значением некоторого другого столбца «id»? У меня есть случай, когда у меня есть неуникальный t2.lastupdate и другой столбец ID, поэтому мне нужно выбрать также по max (ID) (конечно, с учетом производительности)
 Gordon Linoff21 мая 2018 г., 15:18
@AskarIbragimov. , , Вы должны задать вопрос, а не комментарий.
 Askar Ibragimov22 мая 2018 г., 13:56
Решение Вопроса
;with cteRowNumber as (
    select COMPUTERNAME, SERIALNUMBER, USERNAME, LASTIP, LASTUPDATE, SOURCE,
           row_number() over(partition by COMPUTERNAME order by LASTUPDATE desc) as RowNum
        from YourTable
)
select COMPUTERNAME, SERIALNUMBER, USERNAME, LASTIP, LASTUPDATE, SOURCE
    from cteRowNumber
    where RowNum = 1
 Joe Stefanelli20 янв. 2011 г., 21:34
@RyanF: ​​предложение WITH определяетОбщее табличное выражение или CTE. row_number этооконная функция, Обе функции были введены в SQL Server 2005. Надеемся, что эти ссылки помогут вам начать работу в правильном направлении.
 RyanF20 янв. 2011 г., 21:24
Джо, это отлично сработало. Я никогда не знал о предложении WITH и никогда не использовал OVER или PARTITION раньше. Не могли бы вы вкратце сказать мне, что они делают. Я посмотрел их, но теперь уверен, что нахожу правильную информацию.

Ваш ответ на вопрос