У меня есть таблица, которая требует фильтрации по датам.
| Group | Account || Values | Date_ingested |
| -------- | -------- || -------- | -------- |
| X | 3000 || 0 | 2023-01-07 |
| Y | 3000 || null | 2021-02-22 |
Цель состоит в том, чтобы выбрать самую позднюю дату, когда есть несколько точек данных, как в примере выше. Учетная запись 3000 в фрейме данных находится в двух группах, но актуальный и правильный результат должен отражать только группу X, поскольку она была добавлена в блоки данных совсем недавно. Теперь, если я попытаюсь использовать приведенный ниже код с группировкой, код будет выполнен, но функция max будет проигнорирована, и в результатах я получу два результата для учетной записи 3000 с группой X, а затем Y.
Select Group, Account, Values, max(Date_ingested) from datatableX
Если я решу использовать код без группировки, я получаю следующую ошибку
Ошибка в операторе SQL: AnalysisException: последовательность группирующих выражений пуста, а «datatableX.Account» не является агрегатной функцией. Оберните '(max(spark_catalog.datatableX.Date_ingested) AS`max(Date_ingested))' в оконной функции или оберните 'spark_catalog.datatableX.Account' в first() (или first_value), если вам все равно, какое значение Вы получаете.
Однако я не могу найти способ сделать вышеперечисленное. Пробовал читать об агрегатных функциях, но не могу понять концепцию.
Select Group, Account, Values, max(Date_ingested) from datatableX
или
Select Group, Account, Values, max(Date_ingested) from datatableX
group by Group, Account, Values
Вам нужна вся последняя запись для каждой учетной записи, что предполагает фильтрацию, а не агрегацию.
Типичный подход использует rank()
для перечисления записей, имеющих одну и ту же учетную запись, по убыванию даты приема, а затем фильтрует верхнюю запись для каждой группы во внешнем запросе:
select *
from (
select d.*,
row_number() over(partition by account order by date_ingested desc) rn
from datatableX
) d
where rn = 1