Последняя запись за каждый месяц, сгруппированная по столбцу - Impala SQL

У меня есть таблица с размером записи для разных серверов, а также дата сканирования сервера. Мне нужно получать последнюю запись для каждого сервера в каждом месяце. Как я могу сделать это в impala sql. Любая помощь будет оценена по достоинству.

Data    Server  Size
11/4/2017   ABC 200
11/18/2017  ABC 700
11/25/2017  ABC 1009
12/4/2017   ABC 200
12/18/2017  ABC 700
12/20/2017  ABC 1100
1/4/2018    ABC 200
1/18/2018   ABC 700
1/20/2018   ABC 1009
11/4/2017   CAD 200
11/18/2017  CAD 700
11/25/2017  CAD 1009
12/4/2017   CAD 200
12/18/2017  CAD 700
12/20/2017  CAD 1100

ожидаемый результат

Data    Server  Size
11/25/2017  ABC 1009
12/20/2017  ABC 1100
1/20/2018   ABC 1009
11/25/2017  CAD 1009
12/20/2017  CAD 1100

person sudeep    schedule 13.01.2018    source источник
comment
Сначала постарайтесь решить проблему самостоятельно. Сделав это, вы можете объяснить возникшую у вас проблему, включить соответствующие части вашей работы и задать конкретный вопрос, и мы постараемся помочь. Удачи.   -  person peacetype    schedule 13.01.2018


Ответы (2)


SELECT t.*
FROM t
INNER JOIN
(SELECT MONTH(data) AS month, MAX(DAY(data)) AS day, server
 FROM t
 GROUP BY MONTH(data), server) sub
ON (MONTH(t.data) = sub.month AND DAY(t.data) = sub.day AND t.server = sub.server)

Выберите максимальное количество дней в месяц для каждого сервера в подзапросе. Затем присоедините результаты подзапроса к основной таблице. Это позволит исключить строки, которые не являются самыми последними за месяц на сервере.

Протестировано здесь: http://rextester.com/QTIM39711

person kjmerf    schedule 13.01.2018
comment
Большое спасибо, kbball. Я попробую это и поделюсь результатом. - person sudeep; 13.01.2018
comment
Я получаю сообщение об ошибке. Не удалось разрешить ссылку на таблицу. Должен ли я указать имя таблицы, как указано ниже, ВЫБЕРИТЕ t. * ИЗ имени таблицы t ВНУТРЕННЕЕ СОЕДИНЕНИЕ (ВЫБЕРИТЕ МЕСЯЦ (дата сканирования) КАК месяц, МАКС (ДЕНЬ (дата сканирования)) КАК день, кластер ОТ имя таблицы t СГРУППИРОВАТЬ ПО МЕСЯЦ (scandate), кластер) sub ON (МЕСЯЦ (t.scandate) = sub.month AND DAY (t.scandate) = sub.day AND t.cluster = sub.cluster) - person sudeep; 13.01.2018
comment
Ах да, вам нужно заменить t на имя вашей таблицы. Вы видели связанный пример? Это работает для меня, и я не думаю, что там что-то специфично для SQL Server. - person kjmerf; 13.01.2018
comment
Получил приведенное ниже сообщение об ошибке после того, как был задан квалификатор имени таблицы. База данных Cloudera Impala с собственным драйвером обнаружила ошибку при выполнении этого запроса. [Simba][ImpalaJDBCDriver](500051) ОШИБКА при обработке запроса/оператора. Код ошибки: 0, состояние SQL: TStatus (statusCode: ERROR_STATUS, sqlState: HY000, errorMessage: AnalysisException: не удалось разрешить ссылку на столбец/поле: 'scandata') - person sudeep; 16.01.2018

Impala поддерживает оконные функции, поэтому вы можете:

select t.*
from (select t.*,
             row_number() over (partition by server, trunc(data, 'MONTH')
                                order by data desc
                               ) as seqnum
      from t
     ) t
where seqnum = 1;

РЕДАКТИРОВАТЬ:

Вышеприведенное дает последнее значение для каждого сервера. Для одной строки в месяц удалите server из partition by:

select t.*
from (select t.*,
             row_number() over (partition by trunc(data, 'MONTH')
                                order by data desc
                               ) as seqnum
      from t
     ) t
where seqnum = 1;
person Gordon Linoff    schedule 13.01.2018
comment
Большое спасибо за эту быструю помощь ... Я получил следующие результаты Размер сервера данных 20.01.2018 ABC 1009 25.11.2017 CAD 1009 . Ожидалось, что будет получена информация за каждый месяц, как указано ниже, Размер сервера данных 25.11.2017 ABC 1009 20.12.2017 ABC 1100 20.01.2018 ABC 1009 25.11.2017 CAD 1009 20.12.2017 1100 канадских долларов - person sudeep; 13.01.2018