Statistical query (group and sort)

View on GitHubSample viewer app

Query a feature table for statistics, grouping and sorting by different fields.

Query formsheet Query results

Use case

You can use statistical queries, grouping and sorting to process large amounts of data saved in feature tables. This is helpful for identifying trends and relationships within the data, which can be used to support further interpretations and decisions. For example, a health agency can use information on medical conditions occurring throughout a country to identify at-risk areas or demographics, and decide on further action and preventive measures.

How to use the sample

Select a combination of fields and statistic types to include in the query. Choose one or more fields by which to group the results. For example, selecting "State" will calculate the results by state. Choose one or more fields to order results by. Only those fields selected for grouping are valid choices for ordering results. Swipe left to delete any selection. Tap the "Get Statistics" button to execute the query. Results will be displayed in a hierarchical view that is grouped and sorted according to the chosen fields. Tap "Reset" to clear the query.

How it works

  1. Create an AGSServiceFeatureTable using the URL of a feature service and load the table.
  2. Create AGSStatisticDefinition objects and add them to the AGSStatisticsQueryParameters.
  3. To have the results grouped by fields, add the field names to the query parameters' groupByFieldNames array.
  4. To have the results ordered by fields, create AGSOrderBys, specifying the field name and AGSSortOrder. Pass these AGSOrderBys to the parameters' orderByFields collection.
  5. To execute the query, call AGSFeatureTable.queryStatistics(with:completion:).
  6. Get the AGSStatisticQueryResult. From this, you can use AGSStatisticsQueryResult.statisticRecordEnumerator() to loop through and display.

Relevant API

  • AGSField
  • AGSOrderBy
  • AGSQueryParameters
  • AGSServiceFeatureTable
  • AGSStatisticDefinition
  • AGSStatisticRecord
  • AGSStatisticsQueryParameters
  • AGSStatisticsQueryResult
  • AGSStatisticType

About the data

This sample uses a Diabetes, Obesity, and Inactivity by US County feature layer hosted on ArcGIS Online.

Tags

correlation, data, fields, filter, group, sort, statistics, table

Sample Code

AddStatisticDefinitionsViewController.swiftAddStatisticDefinitionsViewController.swiftGroupByFieldsViewController.swiftOrderByFieldsViewController.swiftStatisticalQueryGroupAndSortViewController.swift
Use dark colors for code blocksCopy
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
//
// Copyright 2018 Esri.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

import UIKit
import ArcGIS

protocol AddStatisticDefinitionsViewControllerDelegate: AnyObject {
    func addStatisticDefinition(_ statisticDefinition: AGSStatisticDefinition)
}

class AddStatisticDefinitionsViewController: UITableViewController {
    @IBOutlet private weak var fieldNameCell: UITableViewCell!
    @IBOutlet private weak var statisticTypeCell: UITableViewCell!

    var fieldNames = [String]()
    private var statisticTypes = ["Average", "Count", "Maximum", "Minimum", "StandardDeviation", "Sum", "Variance"]

    var fieldName: String? {
        // fieldNames may be empty if the view controller loaded before the data source loaded
        return fieldNameIndex < fieldNames.count ? fieldNames[fieldNameIndex] : nil
    }

    var fieldNameIndex: Int = 0 {
        didSet {
            fieldNameCell.detailTextLabel?.text = fieldName
        }
    }
    var statisticType: AGSStatisticType = .average {
        didSet {
            statisticTypeCell.detailTextLabel?.text = statisticTypes[statisticType.rawValue]
        }
    }

    // Delegate
    weak var delegate: AddStatisticDefinitionsViewControllerDelegate?

    override func viewDidLoad() {
        super.viewDidLoad()

        fieldNameIndex = 0
        statisticType = .average
    }

    // MARK: - Actions

    @IBAction func addStatisticDefinitionAction(_ sender: Any) {
        // Add statistic definition
        if let fieldName = fieldName {
            let statisticDefinition = AGSStatisticDefinition(onFieldName: fieldName, statisticType: statisticType, outputAlias: nil)
            delegate?.addStatisticDefinition(statisticDefinition)
        }
    }

    // MARK: - UITableViewDelegate

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        let cell = tableView.cellForRow(at: indexPath)
        switch cell {
        case fieldNameCell:
            let controller = OptionsTableViewController(labels: fieldNames, selectedIndex: fieldNameIndex) { (newIndex) in
                self.fieldNameIndex = newIndex
            }
            controller.title = "Field Name"
            show(controller, sender: self)
        case statisticTypeCell:
            let controller = OptionsTableViewController(labels: statisticTypes, selectedIndex: statisticType.rawValue) { (newIndex) in
                self.statisticType = AGSStatisticType(rawValue: newIndex)!
            }
            controller.title = "Statistic Type"
            show(controller, sender: self)
        default:
            break
        }
    }
}

Your browser is no longer supported. Please upgrade your browser for the best experience. See our browser deprecation post for more details.