Skip to content

Attribute Tables

Goal: Learn to read, edit, query, and calculate attribute table fields — the data that makes a map useful.

What you'll learn

  • Anatomy of an attribute table
  • Field types and when to use each
  • Field Calculator basics
  • How attribute tables connect to spatial data

Anatomy of an attribute table

Every vector layer has an attribute table. Each row = one feature. Each column = one field (attribute).

ObjectID Name Population Area_km2 Type
1 Atlanta 498,715 351 City
2 Athens 127,315 308 City
3 Augusta 202,081 791 City
  • ObjectID — auto-generated unique ID. Don't edit it.
  • Geometry / Shape — hidden column with the feature's geometry.
  • The rest — your data.

Field types

Picking the right field type matters for storage, performance, and querying.

Type What it stores Example
Short integer Whole numbers, ±32,767 Census tract count
Long integer Whole numbers, ~±2 billion Population
Float / Double Decimal numbers Latitude, area, NDVI
Text (String) Letters, numbers, symbols City name, ZIP code
Date Dates and times Survey date
Blob / Raster Binary Photos, attachments

ZIP codes and IDs

Store ZIP codes, FIPS codes, and phone numbers as text, not numbers. Otherwise leading zeros disappear (070837083).

Calculating fields

Use the Calculate Field tool to populate values automatically.

# Calculate area in square km
!shape.area@SQUAREKILOMETERS!
!FIRST_NAME! + " " + !LAST_NAME!

def classify(pop):
    if pop > 100000:
        return "Urban"
    elif pop > 10000:
        return "Suburban"
    else:
        return "Rural"
Then in the calculator: classify(!POPULATION!)

!POPULATION! / !AREA_KM2!

Selecting and filtering

Two ways to filter:

  1. Select by AttributesWHERE STATE_NAME = 'Georgia' AND POP > 100000 — see SQL for GIS.
  2. Definition Query — temporarily hides features that don't match a condition. Layer behaves as if the others don't exist.

Definition Query vs Selection

  • Selection = highlights matching features (still visible).
  • Definition Query = filters them out of the layer entirely (only matches show / process).

Joining attribute tables

You can attach a table (CSV, table, or another layer's attributes) to a feature class using a shared field.

flowchart LR
    L[Counties layer] -- FIPS = FIPS --> J((Join))
    T[Population CSV] -- FIPS --> J
    J --> R[Counties + population]

    classDef l fill:#dbeafe,stroke:#1e40af,color:#1e3a8a
    classDef t fill:#fef3c7,stroke:#f59e0b,color:#92400e
    classDef r fill:#dcfce7,stroke:#10b981,color:#065f46
    class L l
    class T t
    class R r
    classDef j fill:#fff,stroke:#4338ca,color:#312e81
    class J j

→ Detailed walkthrough: Joins & Relates

Domains and subtypes (advanced)

In a file geodatabase, you can define:

  • Domain — list of allowed values for a field (e.g., LandUse can only be Residential / Commercial / Industrial)
  • Subtype — different rules for different categories of feature

These reduce data entry errors and enforce consistency.

Best practices

Clean attribute tables = clean analysis

  • Use descriptive field names (POP_2020, not F1).
  • Don't store calculated values that you can derive (e.g., density). Calculate when needed.
  • Document fields with aliases (Field Properties → Alias).
  • Validate types — a numeric field with text in it will break analysis.

Practice

Try this

  1. Download US Counties shapefile (TIGER/Line).
  2. Add a CSV with FIPS, MEDIAN_INCOME for each county.
  3. Join the CSV to the counties using the FIPS field.
  4. Calculate a new field: INCOME_BIN = Low / Mid / High based on MEDIAN_INCOME.
  5. Use Definition Query to show only INCOME_BIN = 'Low' counties.

Next up

Spatial Joins — joining tables based on location.