Проблема с GROUP BY в SOQL

Всем добрый день.
Столкнулся с такой проблемой - непонятно, зачем он вот в такой конструкции

SELECT AccountId, OwnerId, MAX(Amount) max_amount
FROM Opportunity
WHERE AccountId<>’’
GROUP BY AccountId, OwnerId
ORDER BY AccountId

SOQL требует писать LIMIT?image
Т.е., вот так работает
Oleksandr Novikov, [16.11.20 11:37]
SELECT AccountId, OwnerId, MAX(Amount) max_amount
FROM Opportunity
WHERE AccountId<>’’
GROUP BY AccountId, OwnerId
ORDER BY AccountId
LIMIT 2000

без лимита - ругается

1 Like

Вот что пишут в документации.

You can’t use a LIMIT clause in a query that uses an aggregate function, but does not use a GROUP BY clause. For example, the following query is invalid:

Документация

Я это читал. Они пишут “Вы не можете использовать LIMIT, НЕ ИСПОЛЬЗУЯ GROUP BY”.
НО!

  1. как можно использовать, например, MAX(), не используя Group By? Это ж агрегат.
  2. он зачем-то именно требует LIMIT в том выражении с агрегатом и GROUP BY. Зачем он ему?

Исходя из этой документации мы имеем.
Агрегатный запрос выполняется через функцию query() и выполняется как единая операция. количество возможных записей,которые выможете получить это 2000 за один раз. Функция queryMore(), которая описана в ошибке, не поддержвается для выполения агрегатирования в функции query(). По этой причине и требуется лимит.
Суть у вас агрегатирование должно выполняться в рамках одной бат операции(запрос нельзя разделить на несколько одиаковых запросов) потому что сложно контролировать и объеденять результаты в единую выборку. У вас может быть AccountId поле попасть и в первы батч и во второй батч, как итог выборка будет некорректная

1 Like

А как мне тогда получить все результаты запроса? Если их, например, больше 2000?

Тут уже больше идет кастомное решение.
Одним запросом вряд ли можно вменяемо вытащить такие данные.

1 Like

А для чего нужен такой результат?

  • показать пользователю
  • сохранить в базу
  • передать в стороннй сервис
    -использвоать для расчетов

А если ограничить выборку ещё по какому-нибудь полю, как например, CloseDate = THIS_FISCAL_YEAR, Closed: Won Возможно тогда не будет необходимости использовать лимит?

Нужно сформировать для каждого аккаунта список продавцов, которые с ним работают - для пик-листа, который будет использоваться в Customer Community при формировании запроса на закупку самим клиентом. Т.е., при создании запроса ему автоматом в поле Продавец подставляется оунер аккаунта, но он может выбрать другого продавца, привязанного к его аккаунту…
Идея такая: выбрать из опп все аккаунты и всех продавцов, которые вели эти оппы, сгруппировать - и список готов.
В обычном сиквеле я бы просто написал SELECT DISTINCT AccountId, OwnerId FROM Opportunity, но в SOQL такой конструкции нет, поэтому приходится извращаться

Вернее, даже так - из полученного набора данных заполнится релейтед-лист аккаунта, а из него будем формировать пик-лист. Вот ))

Если Вы используете его в Apex-e, попробуйте использовать Aggregate-for loop. Никогда не писал сам, но мне рассказывали про него.
Суть как в soql-for loop:

for(List<AggregateResults> ars : [ /* GROUP BY */]) {
}
1 Like

ОК, спасибо. Попробую