Agregar dados usando QueryExpression

QueryExpression inclui recursos de agrupamento e agregação que permitem calcular soma, média, mínimo, máximo e contagem entre várias linhas de dados.

Para retornar um valor agregado, você deve:

Tipos de agregação

Os tipos de agregação que você pode usar pertencem à XrmAggregateType enum.

Membro de XrmAggregateType Description
Avg O valor médio dos valores de coluna com dados.
Count O número de linhas.
CountColumn O número de linhas com dados nessa coluna.
Max O valor máximo das linhas nessa coluna.
Min O valor mínimo das linhas nessa coluna.
None Use isso quando a coluna for usada para agrupar os dados agregados. O valor HasGroupBy deve ser definido como true.
Sum O valor total dos valores de coluna com dados.

Observe os seguintes pontos:

  • Valores nulos não são considerados ao calcular valores agregados.
  • Os dados agregados são retornados como um AliasedValue.
  • Você pode usar dados de tabelas unidas usando a classe LinkEntity.
  • Você pode aplicar filtros para limitar os resultados como em qualquer consulta.

Exemplo

Digamos que você tenha 10 registros de conta com os seguintes dados:

Número de Funcionários Name Endereço 1 Cidade Data da criação
NULO Conta de exemplo NULO 8/27/2023
1,500 Contoso Pharmaceuticals (exemplo) Redmond 25/03/2023
2,700 Fabrikam, Inc. (exemplo) Lynnwood 25/03/2023
2,900 Blue Yonder Airlines (exemplo) Los Angeles 25/03/2023
2,900 City Power & Light (exemplo) Redmond 25/03/2023
3,900 Coho Winery (exemplo) Phoenix 25/03/2023
4,300 Adventure Works (exemplo) Santa Cruz 25/03/2023
4,800 Alpine Ski House (exemplo) Missoula 25/03/2023
6,000 Litware, Inc. (exemplo) Dallas 25/03/2023
6,200 A. Datum Corporation (exemplo) Redmond 25/03/2023

A consulta a seguir retorna dados agregados para a numberofemployees coluna.

QueryExpression query = new()
{
    EntityName = "account",
    ColumnSet = new ColumnSet(false)
    {
        AttributeExpressions = {
            {
                new XrmAttributeExpression(
                    attributeName: "numberofemployees",
                    alias: "Average",
                    aggregateType: XrmAggregateType.Avg)
            },
            {
                new XrmAttributeExpression(
                    attributeName: "numberofemployees",
                    alias: "Count",
                    aggregateType: XrmAggregateType.Count)
            },
            {
                new XrmAttributeExpression(
                    attributeName: "numberofemployees",
                    alias: "ColumnCount",
                    aggregateType: XrmAggregateType.CountColumn)
            },
            {
                new XrmAttributeExpression(
                    attributeName: "numberofemployees",
                    alias: "Maximum",
                    aggregateType: XrmAggregateType.Max)
            },
            {
                new XrmAttributeExpression(
                    attributeName: "numberofemployees",
                    alias: "Minimum",
                    aggregateType: XrmAggregateType.Min)
            },
            {
                new XrmAttributeExpression(
                    attributeName: "numberofemployees",
                    alias: "Sum",
                    aggregateType: XrmAggregateType.Sum)
            }
        }
    }
};

Os resultados são uma única linha:

 --------------------------------------------------------------
 | Average | Count | ColumnCount | Maximum | Minimum | Sum    |
 --------------------------------------------------------------
 | 3,911   | 10    | 9           | 6,200   | 1,500   | 35,200 |
 --------------------------------------------------------------

Grouping

Agrupe os resultados de uma consulta de agregação adicionando um XrmAttributeExpression com a propriedade HasGroupByAggregateType definida como XrmAggregateType.None.

Ao agrupar, você deve especificar um QueryExpression.Orders com uma OrderExpression que tenha a propriedade Alias definida como o alias do grupo.

Se um agrupado por valor for nulo, ele não aparecerá nos resultados.

Por exemplo, a consulta a seguir retorna a soma dos funcionários e a contagem por cidade:

QueryExpression query = new()
{
      EntityName = "account",
      ColumnSet = new ColumnSet(false)
   {
         AttributeExpressions = {
            {
                  new XrmAttributeExpression(
                     attributeName: "numberofemployees",
                     alias: "Total",
                     aggregateType: XrmAggregateType.Sum)
            },
            {
                  new XrmAttributeExpression(
                     attributeName: "address1_city",
                     alias: "Count",
                     aggregateType: XrmAggregateType.Count)
            },
            {
                  new XrmAttributeExpression(
                     attributeName: "address1_city",
                     alias: "City",
                     aggregateType: XrmAggregateType.None){
                     HasGroupBy = true
            }
         }
      }
   }
};
query.Orders.Add(new OrderExpression(
            attributeName: "address1_city",
            alias: "City",
            orderType: OrderType.Ascending));

A consulta agrupa os resultados por City valor, combinando os resultados das três linhas em que a cidade é 'Redmond'.

Total Contar Cidade
0 1 NULO
6,000 1 Dallas
2,900 1 Los Angeles
2,700 1 Lynnwood
4,800 1 Missoula
3,900 1 Phoenix
10,600 3 Redmond
4,300 1 Santa Cruz

Agrupamento por partes de uma data

Você pode selecionar qual parte da data usar ao agrupar por data. Defina o XrmAttributeExpression.DateTimeGrouping como um dos membros da enumeração XrmDateTimeGrouping.

Membro XrmDateTimeGrouping Description
None Sem agrupamento de data e hora
Day Agrupar por dia
Week Agrupar por semana
Month Agrupar por mês
Quarter Agrupar por Trimestre
Year Agrupar por ano
FiscalPeriod Agrupar por período fiscal
FiscalYear Agrupar por ano fiscal

A consulta a seguir agrupa registros de conta mostrando o número de funcionários quando os registros foram criados:

QueryExpression query = new()
{
    EntityName = "account",
    ColumnSet = new ColumnSet(false)
    {
        AttributeExpressions = {
            {
                new XrmAttributeExpression(
                    attributeName: "numberofemployees",
                    alias: "Total",
                    aggregateType: XrmAggregateType.Sum)
            },
            {
                new XrmAttributeExpression(
                    attributeName: "createdon",
                    alias: "Day",
                    aggregateType: XrmAggregateType.None){
                    HasGroupBy = true,
                    DateTimeGrouping = XrmDateTimeGrouping.Day
                }
            },
            {
                new XrmAttributeExpression(
                    attributeName: "createdon",
                    alias: "Week",
                    aggregateType: XrmAggregateType.None){
                    HasGroupBy = true,
                    DateTimeGrouping = XrmDateTimeGrouping.Week
                }
            },
                                    {
                new XrmAttributeExpression(
                    attributeName: "createdon",
                    alias: "Month",
                    aggregateType: XrmAggregateType.None){
                    HasGroupBy = true,
                    DateTimeGrouping = XrmDateTimeGrouping.Month
                }
            },
            {
                new XrmAttributeExpression(
                    attributeName: "createdon",
                    alias: "Year",
                    aggregateType: XrmAggregateType.None){
                    HasGroupBy = true,
                    DateTimeGrouping = XrmDateTimeGrouping.Year
                }
            },
            {
                new XrmAttributeExpression(
                    attributeName: "createdon",
                    alias: "FiscalPeriod",
                    aggregateType: XrmAggregateType.None){
                    HasGroupBy = true,
                    DateTimeGrouping = XrmDateTimeGrouping.FiscalPeriod
                }
            },
            {
                new XrmAttributeExpression(
                    attributeName: "createdon",
                    alias: "FiscalYear",
                    aggregateType: XrmAggregateType.None){
                    HasGroupBy = true,
                    DateTimeGrouping = XrmDateTimeGrouping.FiscalYear
                }
            }
        }
    }
};
query.Orders.Add(new OrderExpression(
            attributeName: "createdon",
            alias: "Month",
            orderType: OrderType.Ascending));

A tabela a seguir mostra o resultado usando o conjunto de dados de exemplo mencionado anteriormente:

 -----------------------------------------------------------------------
 | Total  | Day | Week | Month | Year  | FiscalPeriod     | FiscalYear |
 -----------------------------------------------------------------------
 | 35,200 | 25  | 12   | 3     | 2,023 | Quarter 1 FY2023 | FY2023     |
 -----------------------------------------------------------------------
 | 0      | 27  | 35   | 8     | 2,023 | Quarter 3 FY2023 | FY2023     |
 -----------------------------------------------------------------------

Exemplo de agrupamento de datas do período fiscal

O exemplo a seguir mostra uma QueryExpression que soma o número total de pedidos atendidos e agrupa o resultado por semestre fiscal e ano fiscal.

QueryExpression query = new()
{
    EntityName = "salesorder",
    ColumnSet = new ColumnSet(false)
    {
        AttributeExpressions = {
            {
                new XrmAttributeExpression(
                    attributeName: "totalamount",
                    alias: "total",
                    aggregateType: XrmAggregateType.Sum)
            },
            {
                new XrmAttributeExpression(
                    attributeName: "datefulfilled",
                    alias: "date",
                    aggregateType: XrmAggregateType.None){
                    HasGroupBy = true,
                    DateTimeGrouping = XrmDateTimeGrouping.FiscalPeriod
                }
            }
        }
    }
};
query.Orders.Add(new OrderExpression(
            attributeName: "datefulfilled",
            alias: "Date",
            orderType: OrderType.Ascending));

Limitações de agregação de QueryExpression

Esta seção descreve os recursos disponíveis usando a agregação com FetchXml que não estão disponíveis no momento usando QueryExpression.

Obter um número distinto com CountColumn

Você não pode obter um número distinto de valores usando CountColumn com QueryExpression. Saiba mais sobre valores de coluna distintos usando FetchXml

Fuso horário ao agrupar por data

O agrupamento por partes de uma data sempre usa a hora UTC e não há como especificar que o fuso horário do usuário deve ser usado, em vez disso , disponível no FetchXml

Agregação de linha

Quando uma tabela tem uma relação hierárquica definida, você não pode retornar uma agregação de linha na coluna de pesquisa para a relação hierárquica. Saiba mais sobre agregações de linha usando FetchXml

Limite por consulta

Não há como especificar um limite de agregação configurável. Saiba mais sobre os limites por consulta usando FetchXml

Erro de limite de registros em consulta agregada

As consultas que retornam valores agregados são limitadas a 50.000 registros. Esse limite ajuda a manter o desempenho e a confiabilidade do sistema. Se os critérios de filtro na consulta retornarem mais de 50.000 registros, você receberá o seguinte erro:

Número: -2147164125
Código: 8004E023
Mensagem: AggregateQueryRecordLimit exceeded. Cannot perform this operation.
Mensagem de erro do cliente: o limite máximo de registro é excedido. Reduzir o número de registros.

Para evitar esse erro, adicione filtros apropriados à consulta para garantir que ela não avalie mais de 50.000 registros. Em seguida, execute a consulta várias vezes e combine os resultados. Os filtros apropriados dependem da natureza dos dados, mas podem ser um intervalo de datas ou um subconjunto de valores em uma coluna de escolha.

Próximas Etapas 

Saiba como contar linhas.