diff --git a/src/libs/convert/ageRangeAggregate.js b/src/libs/convert/ageRangeAggregate.js
new file mode 100644
index 0000000000000000000000000000000000000000..850f00387ec1c5edf45ae72b3696244fc3d9e364
--- /dev/null
+++ b/src/libs/convert/ageRangeAggregate.js
@@ -0,0 +1,38 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+   
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function ageRangeAggregate(id) {
+    switch (id) {
+        case 1:
+        return '0 a 3 anos';
+        case 2:
+        return '4 a 5 anos';
+        case 3:
+        return '6 a 10 anos';
+        case 4:
+        return '11 a 14 anos';
+        case 5:
+        return '15 a 17 anos';
+        case 6:
+        return '18 anos ou mais';
+        default:
+        return 'Não declarada';
+    }
+};
diff --git a/src/libs/convert/educationLevelModAgg.js b/src/libs/convert/educationLevelModAgg.js
new file mode 100644
index 0000000000000000000000000000000000000000..c55a7e8fc3e2f9e2549fff244f61fc57a63ba143
--- /dev/null
+++ b/src/libs/convert/educationLevelModAgg.js
@@ -0,0 +1,46 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function educationLevelMod(id) {
+    switch (id) {
+        case 1:
+        return 'Creche';
+        case 2:
+        return 'Pré-Escola';
+        case 3:
+        return 'Ensino Fundamental - anos iniciais';
+        case 4:
+        return 'Ensino Fundamental - anos finais';
+        case 5:
+        return 'Ensino Médio';
+        case 6:
+        return 'Ensino Medio Integrado ou Normal - tecnico';
+        case 7:
+        return 'EJA - Ensino Fundamental';
+        case 8:
+        return 'EJA - Ensino Médio';
+        case 9:
+        return 'EJA - EF e EM Integrado - tecnico';
+        case 10:
+        return 'Educacao Profissional - concomitante e subsequente';
+        default:
+        return 'Não classificada';
+    }
+};
diff --git a/src/libs/convert/especialEducation.js b/src/libs/convert/especialEducation.js
new file mode 100644
index 0000000000000000000000000000000000000000..4634978459f9e89bc473560a14119b0f196d946e
--- /dev/null
+++ b/src/libs/convert/especialEducation.js
@@ -0,0 +1,31 @@
+/*
+Copyright (C) 2022 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+module.exports = function especialEducation(id) {
+    switch (id) {
+        case 1:
+        return 'Inclusiva';
+        case 2:
+        return 'Exclusiva';
+        default:
+        return 'Não definido';
+    }
+};
+  
diff --git a/src/libs/middlewares/aggregateData.js b/src/libs/middlewares/aggregateData.js
new file mode 100644
index 0000000000000000000000000000000000000000..a721bb1b8d06adf4d48d6ff9251c7a2b0a0f0c9f
--- /dev/null
+++ b/src/libs/middlewares/aggregateData.js
@@ -0,0 +1,63 @@
+const id2str = require(`./id2str`);
+
+/*
+    Middleware que tem como função formatar dados agregados.
+    Dados agregados não podem ser "puxados" do banco de dados da mesma maneira que os dados tradicioanis, dessa maneira é
+    necessário formatá-los para que sigam o padrão.
+*/
+
+// Faz o mapeamento dos filtros com seus respectivos "id2str"
+const convert = {
+    "adm_dependency_detailed": "admDependencyPriv",
+    "age_range": "ageRangeAggregate",
+    "gender": "gender",
+    "ethnic_group": "ethnicGroup",
+    "education_level_mod_agg": "educationLevelModAgg",
+    'integral_time_agg': 'integralTime',
+    'period_agg': 'period',
+    'modality_integral_time': 'educationLevelBasic',
+    'especial_education': 'especialEducation'
+}
+
+function aggregateData(req, res, next) {
+    const newResult = []
+    const aggregateFields = ['gender', 'age_range', 'ethnic_group', 'education_level_mod_agg', 'integral_time_agg', 'period_agg', 'modality_integral_time', 'especial_education']
+    let id;
+    const fields = req.query.dims.split(',');
+    let currentAggregateField;
+    let currentNonAggregateField;
+
+    // Verifica se o filtro passado está presente nos filtros agregados
+    fields.forEach(field => {if (aggregateFields.includes(field)) currentAggregateField = field; else currentNonAggregateField = field});
+    console.log(convert[currentAggregateField])
+    if (currentAggregateField) {
+        req.result.forEach((r) => {
+            // Alguns filtros começam com o id = 0 outros id = 1
+            id = ['ethnic_group', 'integral_time_agg'].includes(currentAggregateField) ? 0 : 1;
+            for (const property in r) {
+                // Dados agregados são identificados com a substring "total_" em sua chave
+                if (property.includes("total_")) {
+                    let data = {
+                        total: r[property],
+                        year: r.year,
+                        [`${currentAggregateField}_id`]: id,
+                        [`${currentAggregateField}_name`]: id2str[convert[currentAggregateField]](id)
+                    }
+    
+                    if (currentNonAggregateField) {
+                        data[`${currentNonAggregateField}_id`] = r[`${currentNonAggregateField}_id`];
+                        data[`${currentNonAggregateField}_name`] = id2str[convert[currentNonAggregateField]](r[`${currentNonAggregateField}_id`]);
+                    }
+    
+                    newResult.push(data)
+                    ++id;
+                }
+            }
+        })
+        req.result = newResult;
+    }
+    console.log(req.result);
+    next();
+}
+
+module.exports = aggregateData;
\ No newline at end of file
diff --git a/src/libs/middlewares/id2str.js b/src/libs/middlewares/id2str.js
index 02273a8bff361981bc0079312881afdf052e439c..06f24488923dba974e4b1fe5ad8eafe10a92d0a4 100644
--- a/src/libs/middlewares/id2str.js
+++ b/src/libs/middlewares/id2str.js
@@ -32,6 +32,7 @@ const agreement = require(`${libs}/convert/agreement`);
 const booleanVariable = require(`${libs}/convert/booleanVariable`);
 const educationLevel = require(`${libs}/convert/educationLevel`);
 const educationLevelMod = require(`${libs}/convert/educationLevelMod`);
+const educationLevelModAgg = require(`${libs}/convert/educationLevelModAgg`);
 const educationLevelShort = require(`${libs}/convert/educationLevelShort`);
 const educationType = require(`${libs}/convert/educationType`);
 const citySize = require(`${libs}/convert/citySize`);
@@ -114,6 +115,8 @@ const regionCode = require(`${libs}/convert/regionCode`);
 const metroCode =  require(`${libs}/convert/metroCode`);
 const modalityShift = require(`${libs}/convert/modalityShift`);
 const incomeRange = require(`${libs}/convert/incomeRange`);
+const ageRangeAggregate = require(`${libs}/convert/ageRangeAggregate`);
+const especialEducation = require(`${libs}/convert/especialEducation`);
 
 const ids = {
     gender_id: gender,
@@ -122,6 +125,7 @@ const ids = {
     education_level_id: educationLevel,
     education_level_basic_id: educationLevelBasic,
     education_level_mod_id: educationLevelMod,
+    education_level_mod_agg_id: educationLevelModAgg,
     education_level_short_id: educationLevelShort,
     adm_dependency_id: admDependency,
     adm_dependency_detailed_id: admDependencyPriv,
@@ -149,6 +153,7 @@ const ids = {
     ethnic_group_pnad_id: ethnicGroupPnad,
     age_range_id: ageRange,
     age_range_all_id: ageRangeAll,
+    age_range_aggregate_id: ageRangeAggregate,
     full_age_range_id: fullAgeRange,
     gender_pnad_id: genderPnad,
     fifth_household_income_id: fifthHouseholdIncome,
@@ -220,7 +225,8 @@ const ids = {
     region_id: regionCode,
     metro_code_id: metroCode,
     modality_shift_id: modalityShift,
-    income_range_id: incomeRange
+    income_range_id: incomeRange,
+    especial_education: especialEducation
 };
 
 function transform(removeId=false) {
@@ -267,6 +273,7 @@ module.exports = {
     educationLevel,
     educationLevelBasic,
     educationLevelMod,
+    educationLevelModAgg,
     educationLevelShort,
     educationLevelSchoolYear,
     admDependency,
@@ -284,6 +291,7 @@ module.exports = {
     contractType,
     ethnicGroupPnad,
     ageRange,
+    ageRangeAggregate,
     ageRangeAll,
     ageStudentCode,
     fullAgeRange,
@@ -349,5 +357,6 @@ module.exports = {
     regionCode,
     metroCode,
     modalityShift,
-    incomeRange
+    incomeRange,
+    especialEducation
 };
diff --git a/src/libs/routes_v1/api.js b/src/libs/routes_v1/api.js
index 53f9e4df0552ed33464f0d34b29dffcd7c02494b..17af82769b1f90fda60afaed8a49d34d37305dc8 100644
--- a/src/libs/routes_v1/api.js
+++ b/src/libs/routes_v1/api.js
@@ -143,6 +143,8 @@ const activity = require(`${libs}/routes_v1/activity`);
 
 const newPnad = require(`${libs}/routes_v1/newPnad`);
 
+const enrollmentAggregate = require(`${libs}/routes_v1/enrollmentAggregate`);
+
 const email = require(`${libs}/routes_v1/email`);
 
 api.get('/', (req, res) => {
@@ -205,6 +207,7 @@ api.use('/universityLocalOffer', universityLocalOffer);
 api.use('/message', message);
 api.use('/course_students', courseStudents);
 api.use('/new_pnad', newPnad);
+api.use('/enrollmentAggregate', enrollmentAggregate);
 
 //Publication 
 api.use('/publication', publication);
diff --git a/src/libs/routes_v1/enrollmentAggregate.js b/src/libs/routes_v1/enrollmentAggregate.js
new file mode 100644
index 0000000000000000000000000000000000000000..e7de586c71cc895ea5fbe79c369b521c80e20893
--- /dev/null
+++ b/src/libs/routes_v1/enrollmentAggregate.js
@@ -0,0 +1,595 @@
+/*
+Copyright (C) 2016 Centro de Computacao Cientifica e Software Livre
+Departamento de Informatica - Universidade Federal do Parana - C3SL/UFPR
+
+This file is part of simcaq-node.
+
+simcaq-node is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+simcaq-node is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with simcaq-node.  If not, see <https://www.gnu.org/licenses/>.
+*/
+
+const express = require('express');
+const { result } = require('lodash');
+
+const enrollmentAggregateApp = express.Router();
+
+const libs = `${process.cwd()}/libs`;
+
+const log = require(`${libs}/log`)(module);
+
+const squel = require('squel');
+
+const query = require(`${libs}/middlewares/query`).query;
+
+const response = require(`${libs}/middlewares/response`);
+
+const ReqQueryFields = require(`${libs}/middlewares/reqQueryFields`);
+
+const aggregateData = require(`${libs}/middlewares/aggregateData`);
+
+const id2str = require(`${libs}/middlewares/id2str`);
+
+const config = require(`${libs}/config`);
+
+const addMissing = require(`${libs}/middlewares/addMissing`);
+
+const cache = require('apicache').options({ debug: config.debug, statusCodes: {include: [200]} }).middleware;
+
+enrollmentAggregateApp.use(cache('15 day'));
+
+let rqf = new ReqQueryFields();
+
+enrollmentAggregateApp.get('/years', (req, res, next) => {
+    req.sql.from('escola')
+    .field('DISTINCT escola.ano_censo', 'year')
+    .where('escola.ano_censo >= 2021')
+    next();
+}, query, response('years'));
+
+enrollmentAggregateApp.get('/adm_dependency', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.admDependency(i)
+        });
+    }
+    next();
+}, response('adm_dependency'));
+
+enrollmentAggregateApp.get('/adm_dependency_detailed', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 9; i++) {
+        req.result.push({
+            id: i, name: id2str.admDependencyPriv(i)
+        });
+    }
+    next();
+}, response('adm_dependency_detailed'));
+
+enrollmentAggregateApp.get('/education_level_mod', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 13; i++) {
+        req.result.push({
+            id: i, name: id2str.educationLevelMod(i)
+        });
+    }
+    next();
+}, response('education_level_mod'));
+
+enrollmentAggregateApp.get('/integral_time', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 3; i++) {
+        req.result.push({
+            id: i, name: id2str.integralTime(i)
+        });
+    }
+    next();
+}, response('education_level_mod')); 
+
+enrollmentAggregateApp.get('/location', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.location(i)
+        });
+    }
+    next();
+}, response('location'));
+
+enrollmentAggregateApp.get('/diff_location', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 4; i++) {
+        req.result.push({
+            id: i, name: id2str.diffLocation(i)
+        });
+    }
+
+    req.result.push({
+        id: 8, name: 'Área onde se localizam povos e comunidades tradicionais'
+    })
+
+    next();
+}, response('diff_location'));
+
+enrollmentAggregateApp.get('/modality_integral_time', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 7; i++) {
+        req.result.push({
+            id: i, name: id2str.educationLevelBasic(i)
+        });
+    }
+
+    next();
+}, response('modality_integral_time'));
+
+enrollmentAggregateApp.get('/gender', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.gender(i)
+        });
+    }
+
+    next();
+}, response('gender'));
+
+enrollmentAggregateApp.get('/age_range', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 7; i++) {
+        req.result.push({
+            id: i, name: id2str.ageRangeAggregate(i)
+        });
+    }
+
+    next();
+}, response('age_range'));
+
+enrollmentAggregateApp.get('/ethnic_group', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 6; i++) {
+        req.result.push({
+            id: i, name: id2str.ethnicGroup(i)
+        });
+    }
+
+    next();
+}, response('ethnic_group'));
+
+enrollmentAggregateApp.get('/period_agg', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.period(i)
+        });
+    }
+
+    next();
+}, response('period_agg'));
+
+enrollmentAggregateApp.get('/region', (req, res, next) => {
+    req.result = []
+
+    for (let i = 0; i <= 5; i++) {
+        req.result.push({
+            id: i, name: id2str.regionCode(i)
+        });
+    }
+
+    next();
+}, response('period_agg'));
+
+enrollmentAggregateApp.get('/state', (req, res, next) => {
+    req.result = []
+    for (let i = 11; i < 54; i++) {
+        if (id2str.stateName(i) !== 'Não declarada') {
+            req.result.push({
+                id: i, name: id2str.stateName(i)
+            });
+        }
+    }
+
+    next();
+}, response('state'));
+
+enrollmentAggregateApp.get('/especial_education', (req, res, next) => {
+    req.result = []
+
+    for (let i = 1; i <= 2; i++) {
+        req.result.push({
+            id: i, name: id2str.especialEducation(i)
+        });
+    }
+
+    next();
+}, response('especial_education'));
+
+
+rqf.addField({
+    name: 'filter',
+    field: false,
+    where: true
+}).addField({
+    name: 'dims',
+    field: true,
+    where: false
+}).addValue({
+    name: 'adm_dependency',
+    table: 'escola',
+    tableField: 'dependencia_adm_id',
+    resultField: 'adm_dependency_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_id'
+    }
+}).addValue({
+    name: 'adm_dependency_detailed',
+    table: 'escola',
+    tableField: 'dependencia_adm_priv',
+    resultField: 'adm_dependency_detailed_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'dependencia_adm_priv'
+    }
+}).addValue({
+    name: 'education_level_mod',
+    table: 'escola',
+    tableField: 'etapas_mod_ensino_segmento_id',
+    resultField: 'education_level_mod_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'etapas_mod_ensino_segmento_id'
+    }
+}).addValue({
+    name:'integral_time',
+    table: 'escola',
+    tableField: 'tempo_integral',
+    resultField: 'integral_time_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'tempo_integral'
+    }
+  }).addValue({
+    name: 'education_level_short',
+    table: 'escola',
+    tableField: 'etapa_resumida',
+    resultField: 'education_level_short_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'etapa_resumida'
+    }
+}).addValue({
+    name: 'region',
+    table: 'regiao',
+    tableField: ['nome', 'id'],
+    resultField: ['region_name', 'region_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'regiao_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'mesoregion',
+    table: 'municipio',
+    tableField: ['nome_mesorregiao', 'mesorregiao_id'],
+    resultField: ['mesoregion_name', 'mesoregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'mesorregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'microregion',
+    table: 'municipio',
+    tableField: ['nome_microrregiao', 'microrregiao_id'],
+    resultField: ['microregion_name', 'microregion_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'microrregiao_id',
+        table: 'municipio'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}).addValue({
+    name: 'min_year',
+    table: 'escola',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '>=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValue({
+    name: 'max_year',
+    table: 'escola',
+    tableField: 'ano_censo',
+    resultField: 'year',
+    where: {
+        relation: '<=',
+        type: 'integer',
+        field: 'ano_censo',
+    },
+}).addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: ['nome', 'id'],
+    resultField: ['state_name', 'state_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'state',
+    table: 'estado',
+    tableField: 'nome',
+    resultField: 'state_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'estado_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: ['nome', 'id'],
+    resultField: ['city_name', 'city_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'city',
+    table: 'municipio',
+    tableField: 'nome',
+    resultField: 'city_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: 'id',
+        foreign: 'municipio_id',
+        foreignTable: 'escola'
+    }
+}, 'filter').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: ['nome_escola', 'id'],
+    resultField: ['school_name', 'school_id'],
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'locale_id',
+    table: 'escola',
+    tableField: 'localizacao_id',
+    resultField: 'locale_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_id'
+    }
+}, 'dims').addValueToField({
+    name: 'school_id',
+    table: 'escola',
+    tableField: 'id',
+    resultField: 'school_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'dims').addValueToField({
+    name: 'school',
+    table: 'escola',
+    tableField: 'nome_escola',
+    resultField: 'school_name',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'id'
+    },
+    join: {
+        primary: ['id', 'ano_censo'],
+        foreign: ['escola_id', 'ano_censo'],
+        foreignTable: 'escola'
+    }
+}, 'filter').addValue({
+    name: 'location',
+    table: 'escola',
+    tableField: 'localizacao_id',
+    resultField: 'location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_id'
+    }
+}).addValue({
+    name: 'diff_location',
+    table: 'escola',
+    tableField: 'localizacao_diferenciada_par',
+    resultField: 'diff_location_id',
+    where: {
+        relation: '=',
+        type: 'integer',
+        field: 'localizacao_diferenciada_par'
+    }
+});
+
+// Return all cities
+enrollmentAggregateApp.get('/', rqf.parse(), rqf.build(), (req, res, next) => {
+
+    console.log(req.query);
+
+    if (req.query.dims && req.query.dims.includes('gender'))
+    {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_bas_masc)', 'total_mas')
+        .field('SUM(escola.qt_mat_bas_fem)', 'total_fem')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo');
+    }
+    else if (req.query.dims && req.query.dims.includes('age_range')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_bas_0_3)', 'total_0_3')
+        .field('SUM(escola.qt_mat_bas_4_5)', 'total_4_5')
+        .field('SUM(escola.qt_mat_bas_6_10)', 'total_6_10')
+        .field('SUM(escola.qt_mat_bas_11_14)', 'total_11_14')
+        .field('SUM(escola.qt_mat_bas_15_17)', 'total_15_17')
+        .field('SUM(escola.qt_mat_bas_18_mais)', 'total_18_mais')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo');
+    }
+    else if (req.query.dims && req.query.dims.includes('ethnic_group')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_bas_nd)', 'total_nd')
+        .field('SUM(escola.qt_mat_bas_branca)', 'total_branca')
+        .field('SUM(escola.qt_mat_bas_preta)', 'total_preta')
+        .field('SUM(escola.qt_mat_bas_parda)', 'total_parda')
+        .field('SUM(escola.qt_mat_bas_amarela)', 'total_amarela')
+        .field('SUM(escola.qt_mat_bas_indigena)', 'total_indigena')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo');
+    }
+    else if (req.query.dims && req.query.dims.includes('education_level_mod_agg')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_inf_cre)', 'total_cre')
+        .field('SUM(escola.qt_mat_inf_pre)', 'total_pre')
+        .field('SUM(escola.qt_mat_fund_ai)', 'total_fund_ai')
+        .field('SUM(escola.qt_mat_fund_af)', 'total_fund_af')
+        .field('SUM(escola.qt_mat_med_agg)', 'total_med')
+        .field('SUM(escola.qt_mat_med_ct + escola.qt_mat_med_nm)', 'total_med_in')
+        .field('SUM(escola.qt_mat_eja_fund_agg)', 'total_eja_fund')
+        .field('SUM(escola.qt_mat_eja_med_agg)', 'total_eja_med')
+        .field('SUM(escola.qt_mat_eja_fund_fic + escola.qt_mat_eja_med_fic + escola.qt_mat_eja_med_tec)', 'total_tec')
+        .field('SUM(escola.qt_mat_prof_agg)', 'total_prof')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo');
+    }
+    else if (req.query.dims && req.query.dims.includes('integral_time_agg')) {
+        req.sql.from('turma,escola')
+        .field('SUM(CASE WHEN turma.tempo_integral=0 then turma.num_matricula ELSE 0 END)', 'total_int_nao')
+        .field('SUM(CASE WHEN turma.tempo_integral=1 then turma.num_matricula ELSE 0 END)', 'total_int')
+        .field('SUM(CASE WHEN turma.tempo_integral=2 then turma.num_matricula ELSE 0 END)', 'total_int_nao_aplica')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo');
+    }
+    else if (req.query.dims && req.query.dims.includes('period_agg')) {
+        req.sql.from('turma,escola')
+        .field('SUM(CASE WHEN turma.turma_turno_id=1 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_matutino')
+        .field('SUM(CASE WHEN turma.turma_turno_id=2 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_vespertino')
+        .field('SUM(CASE WHEN turma.turma_turno_id=3 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_noturno')
+        .field('SUM(CASE WHEN turma.turma_turno_id=4 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_integral')
+        .field('SUM(CASE WHEN turma.turma_turno_id=99 then turma.num_matricula ELSE 0 END)', 'total_qt_mat_bas_semi_ead')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+        .where('turma.tipo_atendimento_id <= 2 and turma.escola_id = escola.id and turma.ano_censo = escola.ano_censo');
+    }
+    else if (req.query.dims && req.query.dims.includes('modality_integral_time')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_inf_cre_int)', 'total_qt_mat_inf_cre_int')
+        .field('SUM(escola.qt_mat_inf_pre_int)', 'total_qt_mat_inf_pre_int')
+        .field('SUM(escola.qt_mat_fund_ai_int)', 'total_qt_mat_fund_ai_int')
+        .field('SUM(escola.qt_mat_fund_af_int)', 'total_qt_mat_fund_af_int')
+        .field('SUM(escola.qt_mat_med_int)', 'total_qt_mat_med_int')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+    }
+    else if (req.query.dims && req.query.dims.includes('especial_education')) {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_esp_cc)', 'total_qt_mat_esp_cc')
+        .field('SUM(escola.qt_mat_esp_ce)', 'total_qt_mat_esp_ce')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo')
+    }
+    else {
+        req.sql.from('escola')
+        .field('SUM(escola.qt_mat_bas)', 'total')
+        .field('escola.ano_censo', 'year')
+        .group('escola.ano_censo')
+        .order('escola.ano_censo');
+    }
+    next();
+}, query, aggregateData, id2str.transform(false), response('enrollment_aggregate'));
+
+module.exports = enrollmentAggregateApp;