Aircraft registration - FAA database
14 September 2025 - Written by ML
This analysis examines the US Federal Aviation Administration (FAA) aircraft registration database, providing insights into the current state of civil aviation in the United States. The database contains detailed information on over 300,000 registered aircraft, 35,000+ deregistered aircraft, and supporting reference data.
who the FAA is
where the FAA sits within the US government
what aircraft registration data there is
how frequently the data is updated
steps to incorporate into MYSQL8
The FAA is described by Wikipedia as a US Federal government agency within the US Department of Transport that regulates civil aviation in the United States. It is organized as:
Source: Grok 2024-09-14 (query: show diagrammatically where the FAA sits within the US government band list for each level the person responsible for it and its superior departments)
U.S. Government
│
└── Executive Branch
│ Responsible: President Donald Trump
│ Superior: None (Head of the Executive Branch)
│
└── U.S. Department of Transportation (DOT)
│ Responsible: Secretary Sean Duffy
│ Superior: President / Executive Branch
│
├── **Federal Aviation Administration (FAA)**
│ │ Responsible: Administrator Bryan Bedford
│ │ Superior: Secretary of Transportation / DOT
│
├── Federal Highway Administration (FHWA)
│ │ Responsible: Administrator Shailen Bhatt
│ │ Superior: Secretary of Transportation / DOT
│
├── Federal Motor Carrier Safety Administration (FMCSA)
│ │ Responsible: Administrator Robin Lee
│ │ Superior: Secretary of Transportation / DOT
│
├── Federal Railroad Administration (FRA)
│ │ Responsible: Administrator Amit Bose
│ │ Superior: Secretary of Transportation / DOT
│
├── Federal Transit Administration (FTA)
│ │ Responsible: Administrator Veronica Vanterpool (acting)
│ │ Superior: Secretary of Transportation / DOT
│
├── Maritime Administration (MARAD)
│ │ Responsible: Administrator Ann Phillips
│ │ Superior: Secretary of Transportation / DOT
│
├── National Highway Traffic Safety Administration (NHTSA)
│ │ Responsible: Administrator Sophie Shulman
│ │ Superior: Secretary of Transportation / DOT
│
├── Pipeline and Hazardous Materials Safety Administration (PHMSA)
│ │ Responsible: Administrator Tristan Brown
│ │ Superior: Secretary of Transportation / DOT
│
├── Surface Transportation Board (STB)
│ │ Responsible: Chair Martin J. Oberman
│ │ Superior: Secretary of Transportation / DOT
│
├── Great Lakes St. Lawrence Seaway Development Corporation (GLS)
│ │ Responsible: Administrator Vacant (acting: U.S. Army Corps of Engineers liaison)
│ │ Superior: Secretary of Transportation / DOT
│
├── Office of the Secretary of Transportation (OST)
│ │ Responsible: Secretary Sean Duffy
│ │ Superior: Secretary of Transportation / DOT
│
├── Office of the Deputy Secretary
│ │ Responsible: Deputy Secretary Vacant (acting: Under Secretary)
│ │ Superior: Secretary of Transportation / DOT
│
├── Office of the General Counsel
│ │ Responsible: General Counsel Sarah Levinson
│ │ Superior: Secretary of Transportation / DOT
│
├── Office of Public Affairs
│ │ Responsible: Assistant Secretary for Public Affairs Vacant (acting)
│ │ Superior: Secretary of Transportation / DOT
│
├── Office of the Chief Information Officer (OCIO)
│ │ Responsible: Chief Information Officer Vacant (acting)
│ │ Superior: Secretary of Transportation / DOT
│
├── Office of Small and Disadvantaged Business Utilization (OSDBU)
│ │ Responsible: Director April McDonald
│ │ Superior: Secretary of Transportation / DOT
│
├── Office of Civil Rights
│ │ Responsible: Director Vacant (acting)
│ │ Superior: Secretary of Transportation / DOT
│
└── Office of Inspector General (OIG)
│ Responsible: Inspector General Eric Soskin
│ Superior: Secretary of Transportation / DOT
And within the FAA the organization structure is:
Source: Grok 2024-09-14 (query: what is the organization structure for the FAA and Bryan Bedford)
U.S. Department of Transportation (DOT)
│ (Superior: Secretary Sean Duffy)
│
└── Federal Aviation Administration (FAA)
│ Responsible: Administrator Bryan Bedford
│ Role: Leads overall policy, safety, and operations; reports to DOT Secretary
│
├── Deputy Administrator
│ │ Responsible: Chris Rocheleau
│ │ Role: Supports Administrator on daily management and initiatives
│
├── Air Traffic Organization (ATO)
│ │ Responsible: Chief Operating Officer (COO) Tim Arel (note: position noted as vacant in some reports due to recent staff changes)
│ │ Role: Manages air navigation services, air traffic control, and the National Airspace System
│ │
│ ├── Air Traffic Service
│ │ │ Responsible: Vice President (acting, post-2025 changes)
│ │
│ ├── Technical Operations
│ │ │ Responsible: Vice President (vacant/acting)
│ │
│ └── Mission Support Services
│ │ Responsible: Director (acting)
│
├── Aviation Safety (AVS)
│ │ Responsible: Associate Administrator David Boulter
│ │ Role: Oversees certification of aircraft, pilots, and safety standards
│ │
│ ├── **Flight Standards Service (FS)**
│ │ │ Responsible: Director (updated May 2025 chart)
│ │
│ ├── Aircraft Certification Service (AIR)
│ │ │ Responsible: Director
│ │
│ └── Safety Assurance and Compliance
│ │ Responsible: Director
│
├── Airports (ARP)
│ │ Responsible: Associate Administrator Chad Kanamori
│ │ Role: Funds airport development and ensures airport safety/compliance
│ │
│ ├── Airport Planning and Programming
│ │ │ Responsible: Director
│ │
│ └── Airport Safety and Standards
│ │ Responsible: Director
│
├── Commercial Space Transportation (AST)
│ │ Responsible: Associate Administrator (vacant; previously Heidi Williams, impacted by 2025 staff reductions)
│ │ Role: Regulates commercial space launches and re-entries
│ │
│ ├── Licensing and Evaluation
│ │ │ Responsible: Director
│ │
│ └── Safety Assurance
│ │ Responsible: Director
│
├── Finance and Management (APM)
│ │ Responsible: Associate Administrator (vacant due to 2025 DOGE-led eliminations)
│ │ Role: Handles budget, HR, acquisitions, and facilities
│ │
│ ├── Financial Services
│ │ │ Responsible: Director (acting)
│ │
│ └── Human Resources
│ │ Responsible: Director
│
├── Headquarters Offices (Policy and Support)
│ │ Role: Provide cross-cutting functions like policy, legal, and communications; report to Administrator
│ │
│ ├── Office of Policy, International Affairs, and Environment (APL)
│ │ │ Responsible: Assistant Administrator (updated July 2025 chart)
│ │ │ Role: Develops policy and handles international aviation
│ │
│ ├── Office of the Chief Counsel (AGC)
│ │ │ Responsible: Chief Counsel
│ │ │ Role: Legal advice and enforcement
│ │
│ ├── Office of Communications
│ │ │ Responsible: Director
│ │ │ Role: Public affairs and media
│ │
│ ├── Office of Civil Rights
│ │ │ Responsible: Director (assistant administrator position eliminated in 2025)
│ │
│ ├── Office of Audit and Evaluation
│ │ │ Responsible: Director (position eliminated in 2025)
│ │
│ └── NextGen (Airspace Modernization)
│ │ Responsible: Associate Administrator (acting)
│ │ Role: Oversees tech upgrades for air traffic management
Responsibility for the upkeep of the aircraft registry:
Source: Grok (query: who is responsible for maintaining the FAA aircraft register? https://registry.faa.gov/aircraftinquiry)
- Responsibility is the FAA Aircraft Registration Branch (also known as the Aircraft Registry)
- Scope of role includes developing, maintaining, and operating the Federal registration and recordation system for U.S. civil aircraft. The branch also provides public access to these records via tools like the Aircraft Inquiry system at https://registry.faa.gov/aircraftinquiry.
For example: issue of aircraft registration certificates (approximately 126,000 annually), processing documents related to aircraft title and interests (about 184,000 per year), reserving and assigning N-Numbers (U.S. nationality marks), and managing the permanent records for over 290,000 active civil aircraft.
- Organizational Placement: The Aircraft Registration Branch operates within the broader FAA structure under the Office of Aviation Safety (AVS). Specifically:
Parent Division: Registry Management Division (AFS-700), part of the **Flight Standards Service (AFS)**.
Location: Based at the Mike Monroney Aeronautical Center in Oklahoma City, Oklahoma, where physical records are maintained and public access is provided through the Public Documents Room.
Oversight: Reports up through the Associate Administrator for Aviation Safety (currently David Boulter) to FAA Administrator Bryan Bedford, and ultimately to the U.S. Department of Transportation (DOT) Secretary Sean Duffy.
Aircraft registration data: FAA registry
Compressed download size: ≈ 60 MB
frequency of update: daily
details of the content of the compressed files can be found in the pdf document.
8 files are included: document pdf (ardata.pdf); Aircraft Registration Master file (MASTER.txt); Aircraft Dealer Applicant file (DEALER.txt); Aircraft Document Index file (DOCINDEX.txt); Aircraft Reference file (ACFTREF.txt); Deregistered Aircraft file (DEREG.txt); Engine Reference file (ENGINE.txt); Reserve N-Number file (RESERVED.txt).
| FAA Aircraft Registry – nightly files | |||
| File | Last updated | Size | Type |
|---|---|---|---|
| DEREG.txt | 12 Sep 2025 23:32 | 276.2 MB | Plain Text |
| MASTER.txt | 12 Sep 2025 23:24 | 188.1 MB | Plain Text |
| RESERVED.txt | 12 Sep 2025 23:25 | 25.1 MB | Plain Text |
| DEALER.txt | 12 Sep 2025 23:18 | 17.9 MB | Plain Text |
| ACFTREF.txt | 12 Sep 2025 22:51 | 14.7 MB | Plain Text |
| DOCINDEX.txt | 12 Sep 2025 23:20 | 1.6 MB | Plain Text |
| ardata.pdf | 8 May 2025 14:29 | 243 KB | PDF Document |
| ENGINE.txt | 12 Sep 2025 22:55 | 232 KB | Plain Text |
Database reconstitution took place in three steps:
text file import into R and data tidy;
import saved sql files into local version of Mysql;
application of indexes to certain fields to smooth processing of database.
# FAA Aircraft Database Import and Data Cleaning Script
# This script imports the MASTER.txt file from the FAA Releasable Aircraft database
# and creates a clean dataframe with properly named columns
# Load required libraries
library(readr)
library(dplyr)
library(stringr)
# Set the file path
file_path <- "MASTER.txt"
# Read the data - it's a comma-separated file
# The file has a header row with column names
cat("Reading FAA Aircraft Database...\n")
aircraft_data <- read_csv(
file_path,
col_types = cols(.default = "c"), # Read all columns as character initially
na = c("", " ", " ") # Treat empty strings and spaces as NA
)
# Display basic information about the dataset
cat("Dataset dimensions:", dim(aircraft_data), "\n")
cat("Number of columns:", ncol(aircraft_data), "\n")
cat("Number of rows:", nrow(aircraft_data), "\n\n")
# Display original column names
cat("Original column names:\n")
print(colnames(aircraft_data))
cat("\n")
# Debug: Check for problematic column names
cat("Checking for problematic column names:\n")
cat("Number of columns:", ncol(aircraft_data), "\n")
cat("Any NA column names:", any(is.na(colnames(aircraft_data))), "\n")
cat("Any empty column names:", any(colnames(aircraft_data) == ""), "\n")
cat("Column names with issues:\n")
problematic_cols <- which(
is.na(colnames(aircraft_data)) | colnames(aircraft_data) == ""
)
if (length(problematic_cols) > 0) {
cat("Problematic column indices:", problematic_cols, "\n")
cat("Problematic column names:", colnames(aircraft_data)[problematic_cols], "\n")
} else {
cat("No problematic column names found.\n")
}
cat("\n")
# Clean up column names - make them MySQL-friendly
original_names <- names(aircraft_data)
new_names <- original_names %>%
tolower() %>% # Convert to lowercase
gsub("-", "_", .) %>% # Replace hyphens with underscores
gsub(" ", "_", .) %>% # Replace spaces with underscores
gsub("__+", "_", .) %>% # Replace multiple underscores with single
gsub("^_|_$", "", .) %>% # Remove leading/trailing underscores
gsub("^[0-9]", "col_\\1", .) # Prefix numeric column names with 'col_'
# Apply the new names
names(aircraft_data) <- new_names
cat("Column names tidied for MySQL compatibility:\n")
for (i in seq_along(original_names)) {
cat(sprintf(" %s -> %s\n", original_names[i], new_names[i]))
}
# Display first few rows to verify the import
cat("First 5 rows of the dataset:\n")
print(head(aircraft_data, 5))
cat("\n")
# Data cleaning (keep everything as character for SQL generation)
cat("Cleaning data...\n")
# Clean text fields - remove extra spaces
aircraft_data <- aircraft_data %>%
mutate(
# Clean text fields - remove extra spaces
name = str_trim(name),
city = str_trim(city),
state = str_trim(state),
zip_code = str_trim(zip_code),
country = str_trim(country),
# Clean n_number - remove extra spaces
n_number = str_trim(n_number),
# Clean serial_number - remove extra spaces
serial_number = str_trim(serial_number)
)
# Function to escape SQL strings and handle NULL values
escape_sql_string <- function(x) {
if (is.na(x) || x == "" || x == " " || x == "NULL") {
return("NULL")
} else {
# Escape single quotes and backslashes
escaped <- gsub("'", "''", x) # Escape single quotes
escaped <- gsub("\\\\", "\\\\\\\\", escaped) # Escape backslashes
return(paste0("'", escaped, "'"))
}
}
# Function to determine appropriate MySQL data types
get_mysql_type <- function(col_name, data) {
# Check if column contains only numeric data
numeric_data <- data[!is.na(data) & data != "" & data != " "]
if (length(numeric_data) > 0) {
is_numeric <- all(grepl("^[0-9.-]+$", numeric_data))
if (is_numeric) {
# Check if it's an integer or decimal
has_decimal <- any(grepl("\\.", numeric_data))
max_length <- max(nchar(numeric_data))
if (has_decimal) {
return(paste0("DECIMAL(", max_length + 2, ",2)"))
} else {
if (max_length <= 3) return("SMALLINT")
if (max_length <= 5) return("INT")
if (max_length <= 10) return("BIGINT")
return(paste0("VARCHAR(", max_length, ")"))
}
}
}
# Check if it's a date column by name
if (grepl("date", tolower(col_name))) {
return("DATE")
}
# Default to VARCHAR with appropriate length
max_length <- max(nchar(data[!is.na(data) & data != "" & data != " "]), default = 0)
if (max_length == 0) max_length <- 1
return(paste0("VARCHAR(", min(max_length * 2, 255), ")"))
}
# Generate CREATE TABLE statement
cat("\nGenerating SQL CREATE TABLE statement...\n")
# Generate column definitions
column_defs <- character()
for (col in names(aircraft_data)) {
mysql_type <- get_mysql_type(col, aircraft_data[[col]])
column_defs <- c(column_defs, paste0(" `", col, "` ", mysql_type))
}
create_table_sql <- paste0(
"-- CREATE TABLE statement for aircraft master data\n",
"-- Generated for MySQL 8.0\n\n",
"DROP TABLE IF EXISTS `aircraft_master`;\n",
"CREATE TABLE `aircraft_master` (\n",
" `id` INT AUTO_INCREMENT PRIMARY KEY,\n",
paste(column_defs, collapse = ",\n"),
"\n);\n\n"
)
# Generate INSERT statements
cat("Generating INSERT statements...\n")
# Process data in batches to avoid memory issues
batch_size <- 1000
total_rows <- nrow(aircraft_data)
num_batches <- ceiling(total_rows / batch_size)
# Prepare column names for INSERT
column_names <- paste0("`", names(aircraft_data), "`", collapse = ", ")
insert_header <- paste0("INSERT INTO `aircraft_master` (", column_names, ") VALUES\n")
# Start building the SQL file content
sql_content <- create_table_sql
cat("Processing", total_rows, "rows in", num_batches, "batches...\n")
for (batch_num in 1:num_batches) {
start_row <- (batch_num - 1) * batch_size + 1
end_row <- min(batch_num * batch_size, total_rows)
cat("Processing batch", batch_num, "of", num_batches, "(rows", start_row, "-", end_row, ")\n")
batch_data <- aircraft_data[start_row:end_row, ]
# Generate VALUES for this batch
values_list <- character()
for (i in 1:nrow(batch_data)) {
row_values <- sapply(batch_data[i, ], escape_sql_string)
values_list <- c(values_list, paste0("(", paste(row_values, collapse = ", "), ")"))
}
# Add batch to SQL content
batch_sql <- paste0(insert_header, paste(values_list, collapse = ",\n"), ";\n\n")
sql_content <- paste0(sql_content, batch_sql)
}
# Write the complete SQL file
sql_output_file <- "aircraft_master_import.sql"
cat("Writing SQL file to:", sql_output_file, "\n")
writeLines(sql_content, sql_output_file)
# Also save as CSV for backup
csv_output_file <- paste0(
"master_clean.csv"
)
cat("Saving CSV backup to:", csv_output_file, "\n")
write_csv(aircraft_data, csv_output_file)
# Generate summary statistics
cat("\nFiles generated successfully!\n")
cat("SQL file size:", file.info(sql_output_file)$size, "bytes\n")
cat("Total rows:", total_rows, "\n")
cat("Columns:", ncol(aircraft_data), "\n")
# Show column information
cat("\nColumn information:\n")
for (col in names(aircraft_data)) {
mysql_type <- get_mysql_type(col, aircraft_data[[col]])
non_null_count <- sum(!is.na(aircraft_data[[col]]) & aircraft_data[[col]] != "" & aircraft_data[[col]] != " ")
cat(sprintf(" %-20s %-20s (%d non-null values)\n", col, mysql_type, non_null_count))
}
cat("\nTo import into MySQL 8, use:\n")
cat("mysql -u your_username -p your_database < ", sql_output_file, "\n")
cat("\nOr from within MySQL:\n")
cat("SOURCE ", sql_output_file, ";\n")
# Script to open and load DEREG.txt into a dataframe
# File: 'DEREG.txt'
# This file contains information about deregistered aircraft
library(readr)
library(dplyr)
library(stringr)
# Set the file path
file_path <- "DEREG.txt"
# Check if file exists
if (!file.exists(file_path)) {
stop("File not found: ", file_path)
}
cat("Loading DEREG.txt into dataframe...\n")
cat("File path:", file_path, "\n")
# Read the CSV file
# Using read_csv from readr for better performance and automatic type detection
dereg_df <- read_csv(file_path,
col_types = cols(.default = "c"), # Read all columns as character initially
show_col_types = FALSE)
# Display basic information about the dataframe
cat("\nDataframe loaded successfully!\n")
cat("Dimensions:", nrow(dereg_df), "rows x", ncol(dereg_df), "columns\n")
cat("Column names:\n")
for (i in seq_along(names(dereg_df))) {
cat(sprintf(" %2d. %s\n", i, names(dereg_df)[i]))
}
# Display first few rows
cat("\nFirst 5 rows:\n")
print(head(dereg_df, 5))
# Display data types
cat("\nData types:\n")
str(dereg_df)
# Basic summary statistics
cat("\nBasic summary:\n")
cat("Total deregistered aircraft records:", nrow(dereg_df), "\n")
# Clean up column names - make them MySQL-friendly
original_names <- names(dereg_df)
new_names <- original_names %>%
tolower() %>% # Convert to lowercase
gsub("-", "_", .) %>% # Replace hyphens with underscores
gsub(" ", "_", .) %>% # Replace spaces with underscores
gsub("__+", "_", .) %>% # Replace multiple underscores with single
gsub("^_|_$", "", .) %>% # Remove leading/trailing underscores
gsub("^[0-9]", "col_\\1", .) # Prefix numeric column names with 'col_'
# Apply the new names
names(dereg_df) <- new_names
cat("Column names tidied for MySQL compatibility:\n")
for (i in seq_along(original_names)) {
cat(sprintf(" %s -> %s\n", original_names[i], new_names[i]))
}
# Function to escape SQL strings and handle NULL values
escape_sql_string <- function(x) {
if (is.na(x) || x == "" || x == " " || x == "NULL") {
return("NULL")
} else {
# Escape single quotes and backslashes
escaped <- gsub("'", "''", x) # Escape single quotes
escaped <- gsub("\\\\", "\\\\\\\\", escaped) # Escape backslashes
return(paste0("'", escaped, "'"))
}
}
# Function to determine appropriate MySQL data types
get_mysql_type <- function(col_name, data) {
# Check if column contains only numeric data
numeric_data <- data[!is.na(data) & data != "" & data != " "]
if (length(numeric_data) > 0) {
is_numeric <- all(grepl("^[0-9.-]+$", numeric_data))
if (is_numeric) {
# Check if it's an integer or decimal
has_decimal <- any(grepl("\\.", numeric_data))
max_length <- max(nchar(numeric_data))
if (has_decimal) {
return(paste0("DECIMAL(", max_length + 2, ",2)"))
} else {
if (max_length <= 3) return("SMALLINT")
if (max_length <= 5) return("INT")
if (max_length <= 10) return("BIGINT")
return(paste0("VARCHAR(", max_length, ")"))
}
}
}
# Check if it's a date column
if (grepl("date", tolower(col_name))) {
return("DATE")
}
# Default to VARCHAR with appropriate length
max_length <- max(nchar(data[!is.na(data) & data != "" & data != " "]), default = 0)
if (max_length == 0) max_length <- 1
return(paste0("VARCHAR(", min(max_length * 2, 255), ")"))
}
# Generate CREATE TABLE statement
cat("\nGenerating SQL CREATE TABLE statement...\n")
# Generate column definitions
column_defs <- character()
for (col in names(dereg_df)) {
mysql_type <- get_mysql_type(col, dereg_df[[col]])
column_defs <- c(column_defs, paste0(" `", col, "` ", mysql_type))
}
create_table_sql <- paste0(
"-- CREATE TABLE statement for deregistered aircraft data\n",
"-- Generated for MySQL 8.0\n\n",
"DROP TABLE IF EXISTS `deregistered_aircraft`;\n",
"CREATE TABLE `deregistered_aircraft` (\n",
" `id` INT AUTO_INCREMENT PRIMARY KEY,\n",
paste(column_defs, collapse = ",\n"),
"\n);\n\n"
)
# Generate INSERT statements
cat("Generating INSERT statements...\n")
# Process data in batches to avoid memory issues
batch_size <- 1000
total_rows <- nrow(dereg_df)
num_batches <- ceiling(total_rows / batch_size)
# Prepare column names for INSERT
column_names <- paste0("`", names(dereg_df), "`", collapse = ", ")
insert_header <- paste0("INSERT INTO `deregistered_aircraft` (", column_names, ") VALUES\n")
# Start building the SQL file content
sql_content <- create_table_sql
cat("Processing", total_rows, "rows in", num_batches, "batches...\n")
for (batch_num in 1:num_batches) {
start_row <- (batch_num - 1) * batch_size + 1
end_row <- min(batch_num * batch_size, total_rows)
cat("Processing batch", batch_num, "of", num_batches, "(rows", start_row, "-", end_row, ")\n")
batch_data <- dereg_df[start_row:end_row, ]
# Generate VALUES for this batch
values_list <- character()
for (i in 1:nrow(batch_data)) {
row_values <- sapply(batch_data[i, ], escape_sql_string)
values_list <- c(values_list, paste0("(", paste(row_values, collapse = ", "), ")"))
}
# Add batch to SQL content
batch_sql <- paste0(insert_header, paste(values_list, collapse = ",\n"), ";\n\n")
sql_content <- paste0(sql_content, batch_sql)
}
# Write the complete SQL file
sql_output_file <- "deregistered_aircraft_import.sql"
cat("Writing SQL file to:", sql_output_file, "\n")
writeLines(sql_content, sql_output_file)
# Also save as CSV for backup
csv_output_file <- paste0(
"dereg_clean.csv"
)
cat("Saving CSV backup to:", csv_output_file, "\n")
write_csv(dereg_df, csv_output_file)
# Generate summary statistics
cat("\nFiles generated successfully!\n")
cat("SQL file size:", file.info(sql_output_file)$size, "bytes\n")
cat("Total rows:", total_rows, "\n")
cat("Columns:", ncol(dereg_df), "\n")
# Show column information
cat("\nColumn information:\n")
for (col in names(dereg_df)) {
mysql_type <- get_mysql_type(col, dereg_df[[col]])
non_null_count <- sum(!is.na(dereg_df[[col]]) & dereg_df[[col]] != "" & dereg_df[[col]] != " ")
cat(sprintf(" %-20s %-20s (%d non-null values)\n", col, mysql_type, non_null_count))
}
cat("\nTo import into MySQL 8, use:\n")
cat("mysql -u your_username -p your_database < ", sql_output_file, "\n")
cat("\nOr from within MySQL:\n")
cat("SOURCE ", sql_output_file, ";\n")
# Script to open and load RESERVED.txt into a dataframe
# File: 'RESERVED.txt'
library(readr)
library(dplyr)
# Set the file path
file_path <- "RESERVED.txt"
# Check if file exists
if (!file.exists(file_path)) {
stop("File not found: ", file_path)
}
cat("Loading RESERVED.txt into dataframe...\n")
cat("File path:", file_path, "\n")
# Read the CSV file
# Using read_csv from readr for better performance and automatic type detection
reserved_df <- read_csv(file_path,
col_types = cols(.default = "c"), # Read all columns as character initially
show_col_types = FALSE)
# Display basic information about the dataframe
cat("\nDataframe loaded successfully!\n")
cat("Dimensions:", nrow(reserved_df), "rows x", ncol(reserved_df), "columns\n")
cat("Column names:\n")
for (i in seq_along(names(reserved_df))) {
cat(sprintf(" %2d. %s\n", i, names(reserved_df)[i]))
}
# Display first few rows
cat("\nFirst 5 rows:\n")
print(head(reserved_df, 5))
# Display data types
cat("\nData types:\n")
str(reserved_df)
# Basic summary statistics
cat("\nBasic summary:\n")
cat("Total records:", nrow(reserved_df), "\n")
cat("Unique N-numbers:", length(unique(reserved_df$`N-NUMBER`)), "\n")
cat("Unique registrants:", length(unique(reserved_df$REGISTRANT)), "\n")
# 1. Tidy column names
cat("\nTidying column names...\n")
# Clean up column names - make them MySQL-friendly
original_names <- names(reserved_df)
new_names <- original_names %>%
tolower() %>% # Convert to lowercase
gsub("-", "_", .) %>% # Replace hyphens with underscores
gsub(" ", "_", .) %>% # Replace spaces with underscores
gsub("__+", "_", .) %>% # Replace multiple underscores with single
gsub("^_|_$", "", .) %>% # Remove leading/trailing underscores
gsub("^[0-9]", "col_\\1", .) # Prefix numeric column names with 'col_'
# Apply the new names
names(reserved_df) <- new_names
cat("Column names tidied for MySQL compatibility:\n")
for (i in seq_along(original_names)) {
cat(sprintf(" %s -> %s\n", original_names[i], new_names[i]))
}
# Function to escape SQL strings and handle NULL values
escape_sql_string <- function(x) {
if (is.na(x) || x == "" || x == " " || x == "NULL") {
return("NULL")
} else {
# Escape single quotes and backslashes
escaped <- gsub("'", "''", x) # Escape single quotes
escaped <- gsub("\\\\", "\\\\\\\\", escaped) # Escape backslashes
return(paste0("'", escaped, "'"))
}
}
# Function to determine appropriate MySQL data types
get_mysql_type <- function(col_name, data) {
# Check if column contains only numeric data
numeric_data <- data[!is.na(data) & data != "" & data != " "]
if (length(numeric_data) > 0) {
is_numeric <- all(grepl("^[0-9.-]+$", numeric_data))
if (is_numeric) {
# Check if it's an integer or decimal
has_decimal <- any(grepl("\\.", numeric_data))
max_length <- max(nchar(numeric_data))
if (has_decimal) {
return(paste0("DECIMAL(", max_length + 2, ",2)"))
} else {
if (max_length <= 3) return("SMALLINT")
if (max_length <= 5) return("INT")
if (max_length <= 10) return("BIGINT")
return(paste0("VARCHAR(", max_length, ")"))
}
}
}
# Check if it's a date column
if (grepl("date", tolower(col_name))) {
return("DATE")
}
# Default to VARCHAR with appropriate length
max_length <- max(nchar(data[!is.na(data) & data != "" & data != " "]), default = 0)
if (max_length == 0) max_length <- 1
return(paste0("VARCHAR(", min(max_length * 2, 255), ")"))
}
# Generate CREATE TABLE statement
cat("\nGenerating SQL CREATE TABLE statement...\n")
# Generate column definitions
column_defs <- character()
for (col in names(reserved_df)) {
mysql_type <- get_mysql_type(col, reserved_df[[col]])
column_defs <- c(column_defs, paste0(" `", col, "` ", mysql_type))
}
create_table_sql <- paste0(
"-- CREATE TABLE statement for reserved numbers data\n",
"-- Generated for MySQL 8.0\n\n",
"DROP TABLE IF EXISTS `reserved_numbers`;\n",
"CREATE TABLE `reserved_numbers` (\n",
" `id` INT AUTO_INCREMENT PRIMARY KEY,\n",
paste(column_defs, collapse = ",\n"),
"\n);\n\n"
)
# Generate INSERT statements
cat("Generating INSERT statements...\n")
# Process data in batches to avoid memory issues
batch_size <- 1000
total_rows <- nrow(reserved_df)
num_batches <- ceiling(total_rows / batch_size)
# Prepare column names for INSERT
column_names <- paste0("`", names(reserved_df), "`", collapse = ", ")
insert_header <- paste0("INSERT INTO `reserved_numbers` (", column_names, ") VALUES\n")
# Start building the SQL file content
sql_content <- create_table_sql
cat("Processing", total_rows, "rows in", num_batches, "batches...\n")
for (batch_num in 1:num_batches) {
start_row <- (batch_num - 1) * batch_size + 1
end_row <- min(batch_num * batch_size, total_rows)
cat("Processing batch", batch_num, "of", num_batches, "(rows", start_row, "-", end_row, ")\n")
batch_data <- reserved_df[start_row:end_row, ]
# Generate VALUES for this batch
values_list <- character()
for (i in 1:nrow(batch_data)) {
row_values <- sapply(batch_data[i, ], escape_sql_string)
values_list <- c(values_list, paste0("(", paste(row_values, collapse = ", "), ")"))
}
# Add batch to SQL content
batch_sql <- paste0(insert_header, paste(values_list, collapse = ",\n"), ";\n\n")
sql_content <- paste0(sql_content, batch_sql)
}
# Write the complete SQL file
sql_output_file <- "reserved_numbers_import.sql"
cat("Writing SQL file to:", sql_output_file, "\n")
writeLines(sql_content, sql_output_file)
# Also save as CSV for backup
csv_output_file <- paste0(
"reserved_clean.csv"
)
cat("Saving CSV backup to:", csv_output_file, "\n")
write_csv(reserved_df, csv_output_file)
# Generate summary statistics
cat("\nFiles generated successfully!\n")
cat("SQL file size:", file.info(sql_output_file)$size, "bytes\n")
cat("Total rows:", total_rows, "\n")
cat("Columns:", ncol(reserved_df), "\n")
# Show column information
cat("\nColumn information:\n")
for (col in names(reserved_df)) {
mysql_type <- get_mysql_type(col, reserved_df[[col]])
non_null_count <- sum(!is.na(reserved_df[[col]]) & reserved_df[[col]] != "" & reserved_df[[col]] != " ")
cat(sprintf(" %-20s %-20s (%d non-null values)\n", col, mysql_type, non_null_count))
}
cat("\nTo import into MySQL 8, use:\n")
cat("mysql -u your_username -p your_database < ", sql_output_file, "\n")
cat("\nOr from within MySQL:\n")
cat("SOURCE ", sql_output_file, ";\n")
# Script to open and load DOCINDEX.txt into a dataframe
# File: 'DOCINDEX.txt'
# This file contains information about aircraft documentation and certification records
library(readr)
library(dplyr)
library(stringr)
library(tidyr)
# Set the file path
file_path <- "DOCINDEX.txt"
# Check if file exists
if (!file.exists(file_path)) {
stop("File not found: ", file_path)
}
cat("Loading DOCINDEX.txt into dataframe...\n")
cat("File path:", file_path, "\n")
# Read the CSV file
# Using read_csv from readr for better performance and automatic type detection
docindex_df <- read_csv(file_path,
col_types = cols(.default = "c"), # Read all columns as character initially
show_col_types = FALSE)
# Display basic information about the dataframe
cat("\nDataframe loaded successfully!\n")
cat("Dimensions:", nrow(docindex_df), "rows x", ncol(docindex_df), "columns\n")
cat("Column names:\n")
for (i in seq_along(names(docindex_df))) {
cat(sprintf(" %2d. %s\n", i, names(docindex_df)[i]))
}
# Display first few rows
cat("\nFirst 5 rows:\n")
print(head(docindex_df, 5))
# Display data types
cat("\nData types:\n")
str(docindex_df)
# Clean up column names - make them MySQL-friendly
original_names <- names(docindex_df)
new_names <- original_names %>%
tolower() %>% # Convert to lowercase
gsub("-", "_", .) %>% # Replace hyphens with underscores
gsub(" ", "_", .) %>% # Replace spaces with underscores
gsub("__+", "_", .) %>% # Replace multiple underscores with single
gsub("^_|_$", "", .) %>% # Remove leading/trailing underscores
gsub("^[0-9]", "col_\\1", .) # Prefix numeric column names with 'col_'
# Apply the new names
names(docindex_df) <- new_names
cat("Column names tidied for MySQL compatibility:\n")
for (i in seq_along(original_names)) {
cat(sprintf(" %s -> %s\n", original_names[i], new_names[i]))
}
# Function to escape SQL strings and handle NULL values
escape_sql_string <- function(x) {
if (is.na(x) || x == "" || x == " " || x == "NULL") {
return("NULL")
} else {
# Escape single quotes and backslashes
escaped <- gsub("'", "''", x) # Escape single quotes
escaped <- gsub("\\\\", "\\\\\\\\", escaped) # Escape backslashes
return(paste0("'", escaped, "'"))
}
}
# Function to determine appropriate MySQL data types
get_mysql_type <- function(col_name, data) {
# Check if column contains only numeric data
numeric_data <- data[!is.na(data) & data != "" & data != " "]
if (length(numeric_data) > 0) {
is_numeric <- all(grepl("^[0-9.-]+$", numeric_data))
if (is_numeric) {
# Check if it's an integer or decimal
has_decimal <- any(grepl("\\.", numeric_data))
max_length <- max(nchar(numeric_data))
if (has_decimal) {
return(paste0("DECIMAL(", max_length + 2, ",2)"))
} else {
if (max_length <= 3) return("SMALLINT")
if (max_length <= 5) return("INT")
if (max_length <= 10) return("BIGINT")
return(paste0("VARCHAR(", max_length, ")"))
}
}
}
# Check if it's a date column
if (grepl("date", tolower(col_name))) {
return("DATE")
}
# Default to VARCHAR with appropriate length
max_length <- max(nchar(data[!is.na(data) & data != "" & data != " "]), default = 0)
if (max_length == 0) max_length <- 1
return(paste0("VARCHAR(", min(max_length * 2, 255), ")"))
}
# Generate CREATE TABLE statement
cat("\nGenerating SQL CREATE TABLE statement...\n")
# Generate column definitions
column_defs <- character()
for (col in names(docindex_df)) {
mysql_type <- get_mysql_type(col, docindex_df[[col]])
column_defs <- c(column_defs, paste0(" `", col, "` ", mysql_type))
}
create_table_sql <- paste0(
"-- CREATE TABLE statement for documentation index data\n",
"-- Generated for MySQL 8.0\n\n",
"DROP TABLE IF EXISTS `documentation_index`;\n",
"CREATE TABLE `documentation_index` (\n",
" `id` INT AUTO_INCREMENT PRIMARY KEY,\n",
paste(column_defs, collapse = ",\n"),
"\n);\n\n"
)
# Generate INSERT statements
cat("Generating INSERT statements...\n")
# Process data in batches to avoid memory issues
batch_size <- 1000
total_rows <- nrow(docindex_df)
num_batches <- ceiling(total_rows / batch_size)
# Prepare column names for INSERT
column_names <- paste0("`", names(docindex_df), "`", collapse = ", ")
insert_header <- paste0("INSERT INTO `documentation_index` (", column_names, ") VALUES\n")
# Start building the SQL file content
sql_content <- create_table_sql
cat("Processing", total_rows, "rows in", num_batches, "batches...\n")
for (batch_num in 1:num_batches) {
start_row <- (batch_num - 1) * batch_size + 1
end_row <- min(batch_num * batch_size, total_rows)
cat("Processing batch", batch_num, "of", num_batches, "(rows", start_row, "-", end_row, ")\n")
batch_data <- docindex_df[start_row:end_row, ]
# Generate VALUES for this batch
values_list <- character()
for (i in 1:nrow(batch_data)) {
row_values <- sapply(batch_data[i, ], escape_sql_string)
values_list <- c(values_list, paste0("(", paste(row_values, collapse = ", "), ")"))
}
# Add batch to SQL content
batch_sql <- paste0(insert_header, paste(values_list, collapse = ",\n"), ";\n\n")
sql_content <- paste0(sql_content, batch_sql)
}
# Write the complete SQL file
sql_output_file <- "documentation_index_import.sql"
cat("Writing SQL file to:", sql_output_file, "\n")
writeLines(sql_content, sql_output_file)
# Also save as CSV for backup
csv_output_file <- paste0(
"docindex_clean.csv"
)
cat("Saving CSV backup to:", csv_output_file, "\n")
write_csv(docindex_df, csv_output_file)
# Generate summary statistics
cat("\nFiles generated successfully!\n")
cat("SQL file size:", file.info(sql_output_file)$size, "bytes\n")
cat("Total rows:", total_rows, "\n")
cat("Columns:", ncol(docindex_df), "\n")
# Show column information
cat("\nColumn information:\n")
for (col in names(docindex_df)) {
mysql_type <- get_mysql_type(col, docindex_df[[col]])
non_null_count <- sum(!is.na(docindex_df[[col]]) & docindex_df[[col]] != "" & docindex_df[[col]] != " ")
cat(sprintf(" %-20s %-20s (%d non-null values)\n", col, mysql_type, non_null_count))
}
cat("\nTo import into MySQL 8, use:\n")
cat("mysql -u your_username -p your_database < ", sql_output_file, "\n")
cat("\nOr from within MySQL:\n")
cat("SOURCE ", sql_output_file, ";\n")
# Script to open and load DEALER.txt into a dataframe
# File: 'DEALER.txt'
library(readr)
library(dplyr)
# Set the file path
file_path <- "DEALER.txt"
# Check if file exists
if (!file.exists(file_path)) {
stop("File not found: ", file_path)
}
cat("Loading DEALER.txt into dataframe...\n")
cat("File path:", file_path, "\n")
# Read the CSV file
# Using read_csv from readr for better performance and automatic type detection
dealer_df <- read_csv(file_path,
col_types = cols(.default = "c"), # Read all columns as character initially
show_col_types = FALSE)
# Display basic information about the dataframe
cat("\nDataframe loaded successfully!\n")
cat("Dimensions:", nrow(dealer_df), "rows x", ncol(dealer_df), "columns\n")
cat("Column names:\n")
for (i in seq_along(names(dealer_df))) {
cat(sprintf(" %2d. %s\n", i, names(dealer_df)[i]))
}
# Display first few rows
cat("\nFirst 5 rows:\n")
print(head(dealer_df, 5))
# Display data types
cat("\nData types:\n")
str(dealer_df)
# 1. Tidy column names
cat("\nTidying column names...\n")
# Clean up column names - make them MySQL-friendly
original_names <- names(dealer_df)
new_names <- original_names %>%
tolower() %>% # Convert to lowercase
gsub("-", "_", .) %>% # Replace hyphens with underscores
gsub(" ", "_", .) %>% # Replace spaces with underscores
gsub("__+", "_", .) %>% # Replace multiple underscores with single
gsub("^_|_$", "", .) %>% # Remove leading/trailing underscores
gsub("^[0-9]", "col_\\1", .) # Prefix numeric column names with 'col_'
# Apply the new names
names(dealer_df) <- new_names
cat("Column names tidied for MySQL compatibility:\n")
for (i in seq_along(original_names)) {
cat(sprintf(" %s -> %s\n", original_names[i], new_names[i]))
}
# Function to escape SQL strings and handle NULL values
escape_sql_string <- function(x) {
if (is.na(x) || x == "" || x == " " || x == "NULL") {
return("NULL")
} else {
# Escape single quotes and backslashes
escaped <- gsub("'", "''", x) # Escape single quotes
escaped <- gsub("\\\\", "\\\\\\\\", escaped) # Escape backslashes
return(paste0("'", escaped, "'"))
}
}
# Function to determine appropriate MySQL data types
get_mysql_type <- function(col_name, data) {
# Check if column contains only numeric data
numeric_data <- data[!is.na(data) & data != "" & data != " "]
if (length(numeric_data) > 0) {
is_numeric <- all(grepl("^[0-9.-]+$", numeric_data))
if (is_numeric) {
# Check if it's an integer or decimal
has_decimal <- any(grepl("\\.", numeric_data))
max_length <- max(nchar(numeric_data))
if (has_decimal) {
return(paste0("DECIMAL(", max_length + 2, ",2)"))
} else {
if (max_length <= 3) return("SMALLINT")
if (max_length <= 5) return("INT")
if (max_length <= 10) return("BIGINT")
return(paste0("VARCHAR(", max_length, ")"))
}
}
}
# Check if it's a date column
if (grepl("date", tolower(col_name))) {
return("DATE")
}
# Default to VARCHAR with appropriate length
max_length <- max(nchar(data[!is.na(data) & data != "" & data != " "]), default = 0)
if (max_length == 0) max_length <- 1
return(paste0("VARCHAR(", min(max_length * 2, 255), ")"))
}
# Generate CREATE TABLE statement
cat("\nGenerating SQL CREATE TABLE statement...\n")
# Generate column definitions
column_defs <- character()
for (col in names(dealer_df)) {
mysql_type <- get_mysql_type(col, dealer_df[[col]])
column_defs <- c(column_defs, paste0(" `", col, "` ", mysql_type))
}
create_table_sql <- paste0(
"-- CREATE TABLE statement for dealer data\n",
"-- Generated for MySQL 8.0\n\n",
"DROP TABLE IF EXISTS `dealers`;\n",
"CREATE TABLE `dealers` (\n",
" `id` INT AUTO_INCREMENT PRIMARY KEY,\n",
paste(column_defs, collapse = ",\n"),
"\n);\n\n"
)
# Generate INSERT statements
cat("Generating INSERT statements...\n")
# Process data in batches to avoid memory issues
batch_size <- 1000
total_rows <- nrow(dealer_df)
num_batches <- ceiling(total_rows / batch_size)
# Prepare column names for INSERT
column_names <- paste0("`", names(dealer_df), "`", collapse = ", ")
insert_header <- paste0("INSERT INTO `dealers` (", column_names, ") VALUES\n")
# Start building the SQL file content
sql_content <- create_table_sql
cat("Processing", total_rows, "rows in", num_batches, "batches...\n")
for (batch_num in 1:num_batches) {
start_row <- (batch_num - 1) * batch_size + 1
end_row <- min(batch_num * batch_size, total_rows)
cat("Processing batch", batch_num, "of", num_batches, "(rows", start_row, "-", end_row, ")\n")
batch_data <- dealer_df[start_row:end_row, ]
# Generate VALUES for this batch
values_list <- character()
for (i in 1:nrow(batch_data)) {
row_values <- sapply(batch_data[i, ], escape_sql_string)
values_list <- c(values_list, paste0("(", paste(row_values, collapse = ", "), ")"))
}
# Add batch to SQL content
batch_sql <- paste0(insert_header, paste(values_list, collapse = ",\n"), ";\n\n")
sql_content <- paste0(sql_content, batch_sql)
}
# Write the complete SQL file
sql_output_file <- "dealers_import.sql"
cat("Writing SQL file to:", sql_output_file, "\n")
writeLines(sql_content, sql_output_file)
# Also save as CSV for backup
csv_output_file <- paste0(
"dealer_clean.csv"
)
cat("Saving CSV backup to:", csv_output_file, "\n")
write_csv(dealer_df, csv_output_file)
# Generate summary statistics
cat("\nFiles generated successfully!\n")
cat("SQL file size:", file.info(sql_output_file)$size, "bytes\n")
cat("Total rows:", total_rows, "\n")
cat("Columns:", ncol(dealer_df), "\n")
# Show column information
cat("\nColumn information:\n")
for (col in names(dealer_df)) {
mysql_type <- get_mysql_type(col, dealer_df[[col]])
non_null_count <- sum(!is.na(dealer_df[[col]]) & dealer_df[[col]] != "" & dealer_df[[col]] != " ")
cat(sprintf(" %-20s %-20s (%d non-null values)\n", col, mysql_type, non_null_count))
}
cat("\nTo import into MySQL 8, use:\n")
cat("mysql -u your_username -p your_database < ", sql_output_file, "\n")
cat("\nOr from within MySQL:\n")
cat("SOURCE ", sql_output_file, ";\n")
# Script to open and load ACFTREF.txt into a dataframe
# File: 'ACFTREF.txt'
library(readr)
library(dplyr)
# Set the file path
file_path <- "ACFTREF.txt"
# Check if file exists
if (!file.exists(file_path)) {
stop("File not found: ", file_path)
}
cat("Loading ACFTREF.txt into dataframe...\n")
cat("File path:", file_path, "\n")
# Read the CSV file
# Using read_csv from readr for better performance and automatic type detection
acftref_df <- read_csv(file_path,
col_types = cols(.default = "c"), # Read all columns as character initially
show_col_types = FALSE)
# Display basic information about the dataframe
cat("\nDataframe loaded successfully!\n")
cat("Dimensions:", nrow(acftref_df), "rows x", ncol(acftref_df), "columns\n")
cat("Column names:\n")
for (i in seq_along(names(acftref_df))) {
cat(sprintf(" %2d. %s\n", i, names(acftref_df)[i]))
}
# Display first few rows
cat("\nFirst 5 rows:\n")
print(head(acftref_df, 5))
# Display data types
cat("\nData types:\n")
str(acftref_df)
# 1. Tidy column names
cat("\nTidying column names...\n")
# Remove the extra empty column if it exists
if ("...14" %in% names(acftref_df)) {
acftref_df <- acftref_df %>% select(-"...14")
cat("Removed empty column '...14'\n")
}
# Clean up column names - make them MySQL-friendly
original_names <- names(acftref_df)
new_names <- original_names %>%
tolower() %>% # Convert to lowercase
gsub("-", "_", .) %>% # Replace hyphens with underscores
gsub(" ", "_", .) %>% # Replace spaces with underscores
gsub("__+", "_", .) %>% # Replace multiple underscores with single
gsub("^_|_$", "", .) %>% # Remove leading/trailing underscores
gsub("^[0-9]", "col_\\1", .) # Prefix numeric column names with 'col_'
# Apply the new names
names(acftref_df) <- new_names
cat("Column names tidied for MySQL compatibility:\n")
for (i in seq_along(original_names)) {
cat(sprintf(" %s -> %s\n", original_names[i], new_names[i]))
}
# Function to escape SQL strings and handle NULL values
escape_sql_string <- function(x) {
if (is.na(x) || x == "" || x == " " || x == "NULL") {
return("NULL")
} else {
# Escape single quotes and backslashes
escaped <- gsub("'", "''", x) # Escape single quotes
escaped <- gsub("\\\\", "\\\\\\\\", escaped) # Escape backslashes
return(paste0("'", escaped, "'"))
}
}
# Function to determine appropriate MySQL data types
get_mysql_type <- function(col_name, data) {
# Check if column contains only numeric data
numeric_data <- data[!is.na(data) & data != "" & data != " "]
if (length(numeric_data) > 0) {
is_numeric <- all(grepl("^[0-9.-]+$", numeric_data))
if (is_numeric) {
# Check if it's an integer or decimal
has_decimal <- any(grepl("\\.", numeric_data))
max_length <- max(nchar(numeric_data))
if (has_decimal) {
return(paste0("DECIMAL(", max_length + 2, ",2)"))
} else {
if (max_length <= 3) return("SMALLINT")
if (max_length <= 5) return("INT")
if (max_length <= 10) return("BIGINT")
return(paste0("VARCHAR(", max_length, ")"))
}
}
}
# Check if it's a date column
if (grepl("date", tolower(col_name))) {
return("DATE")
}
# Default to VARCHAR with appropriate length
max_length <- max(nchar(data[!is.na(data) & data != "" & data != " "]), default = 0)
if (max_length == 0) max_length <- 1
return(paste0("VARCHAR(", min(max_length * 2, 255), ")"))
}
# Generate CREATE TABLE statement
cat("\nGenerating SQL CREATE TABLE statement...\n")
# Generate column definitions
column_defs <- character()
for (col in names(acftref_df)) {
mysql_type <- get_mysql_type(col, acftref_df[[col]])
column_defs <- c(column_defs, paste0(" `", col, "` ", mysql_type))
}
create_table_sql <- paste0(
"-- CREATE TABLE statement for aircraft reference data\n",
"-- Generated for MySQL 8.0\n\n",
"DROP TABLE IF EXISTS `aircraft_reference`;\n",
"CREATE TABLE `aircraft_reference` (\n",
" `id` INT AUTO_INCREMENT PRIMARY KEY,\n",
paste(column_defs, collapse = ",\n"),
"\n);\n\n"
)
# Generate INSERT statements
cat("Generating INSERT statements...\n")
# Process data in batches to avoid memory issues
batch_size <- 1000
total_rows <- nrow(acftref_df)
num_batches <- ceiling(total_rows / batch_size)
# Prepare column names for INSERT
column_names <- paste0("`", names(acftref_df), "`", collapse = ", ")
insert_header <- paste0("INSERT INTO `aircraft_reference` (", column_names, ") VALUES\n")
# Start building the SQL file content
sql_content <- create_table_sql
cat("Processing", total_rows, "rows in", num_batches, "batches...\n")
for (batch_num in 1:num_batches) {
start_row <- (batch_num - 1) * batch_size + 1
end_row <- min(batch_num * batch_size, total_rows)
cat("Processing batch", batch_num, "of", num_batches, "(rows", start_row, "-", end_row, ")\n")
batch_data <- acftref_df[start_row:end_row, ]
# Generate VALUES for this batch
values_list <- character()
for (i in 1:nrow(batch_data)) {
row_values <- sapply(batch_data[i, ], escape_sql_string)
values_list <- c(values_list, paste0("(", paste(row_values, collapse = ", "), ")"))
}
# Add batch to SQL content
batch_sql <- paste0(insert_header, paste(values_list, collapse = ",\n"), ";\n\n")
sql_content <- paste0(sql_content, batch_sql)
}
# Write the complete SQL file
sql_output_file <- "aircraft_reference_import.sql"
cat("Writing SQL file to:", sql_output_file, "\n")
writeLines(sql_content, sql_output_file)
# Also save as CSV for backup
csv_output_file <- paste0(
"acftref_clean.csv"
)
cat("Saving CSV backup to:", csv_output_file, "\n")
write_csv(acftref_df, csv_output_file)
# Generate summary statistics
cat("\nFiles generated successfully!\n")
cat("SQL file size:", file.info(sql_output_file)$size, "bytes\n")
cat("Total rows:", total_rows, "\n")
cat("Columns:", ncol(acftref_df), "\n")
# Show column information
cat("\nColumn information:\n")
for (col in names(acftref_df)) {
mysql_type <- get_mysql_type(col, acftref_df[[col]])
non_null_count <- sum(!is.na(acftref_df[[col]]) & acftref_df[[col]] != "" & acftref_df[[col]] != " ")
cat(sprintf(" %-20s %-20s (%d non-null values)\n", col, mysql_type, non_null_count))
}
cat("\nTo import into MySQL 8, use:\n")
cat("mysql -u your_username -p your_database < ", sql_output_file, "\n")
cat("\nOr from within MySQL:\n")
cat("SOURCE ", sql_output_file, ";\n")
# Script to open and load ENGINE.txt into a dataframe
# File: 'ENGINE.txt'
library(readr)
library(dplyr)
library(stringr)
library(tidyr)
# Set the file path
file_path <- "engine.txt"
# Check if file exists
if (!file.exists(file_path)) {
stop("File not found: ", file_path)
}
cat("Loading ENGINE.txt into dataframe...\n")
cat("File path:", file_path, "\n")
# Read the CSV file
# Using read_csv from readr for better performance and automatic type detection
engine_df <- read_csv(file_path,
col_types = cols(.default = "c"), # Read all columns as character initially
show_col_types = FALSE)
# Display basic information about the dataframe
cat("\nDataframe loaded successfully!\n")
cat("Dimensions:", nrow(engine_df), "rows x", ncol(engine_df), "columns\n")
cat("Column names:\n")
for (i in seq_along(names(engine_df))) {
cat(sprintf(" %2d. %s\n", i, names(engine_df)[i]))
}
# Display first few rows
cat("\nFirst 5 rows:\n")
print(head(engine_df, 5))
# Display data types
cat("\nData types:\n")
str(engine_df)
# Basic summary statistics
cat("\nBasic summary:\n")
cat("Total records:", nrow(engine_df), "\n")
# Check for unique values in key columns
if ("MFR" %in% names(engine_df)) {
cat("Unique manufacturers:", length(unique(engine_df$MFR)), "\n")
cat("Sample manufacturers:\n")
sample_mfrs <- unique(engine_df$MFR)[1:10]
for (mfr in sample_mfrs) {
cat(" -", mfr, "\n")
}
}
if ("MODEL" %in% names(engine_df)) {
cat("\nUnique models:", length(unique(engine_df$MODEL)), "\n")
cat("Sample models:\n")
sample_models <- unique(engine_df$MODEL)[1:10]
for (model in sample_models) {
cat(" -", model, "\n")
}
}
# Check for engine type information
if ("TYPE" %in% names(engine_df)) {
cat("\nEngine types:\n")
engine_types <- table(engine_df$TYPE, useNA = "ifany")
print(engine_types)
# Add engine type descriptions (from FAA ardata.pdf)
cat("\nEngine type descriptions:\n")
type_descriptions <- c(
"0" = "None",
"1" = "Reciprocating",
"2" = "Turbo-prop",
"3" = "Turbo-shaft",
"4" = "Turbo-jet",
"5" = "Turbo-fan",
"6" = "Ramjet",
"7" = "2 Cycle",
"8" = "4 Cycle",
"9" = "Unknown",
"10" = "Electric",
"11" = "Rotary"
)
for (type_code in names(engine_types)) {
if (type_code %in% names(type_descriptions)) {
cat(" Type", type_code, ":", type_descriptions[type_code], "(", engine_types[type_code], "engines)\n")
} else {
cat(" Type", type_code, ": Unknown (", engine_types[type_code], "engines)\n")
}
}
}
# Check for horsepower information
if ("HORSEPOWER" %in% names(engine_df)) {
cat("\nHorsepower summary:\n")
# Convert to numeric for summary
hp_numeric <- as.numeric(engine_df$HORSEPOWER)
cat("Horsepower range:", min(hp_numeric, na.rm = TRUE), "to", max(hp_numeric, na.rm = TRUE), "\n")
cat("Average horsepower:", round(mean(hp_numeric, na.rm = TRUE), 2), "\n")
cat("Median horsepower:", median(hp_numeric, na.rm = TRUE), "\n")
}
# Check for thrust information
if ("THRUST" %in% names(engine_df)) {
cat("\nThrust summary:\n")
# Convert to numeric for summary
thrust_numeric <- as.numeric(engine_df$THRUST)
cat("Thrust range:", min(thrust_numeric, na.rm = TRUE), "to", max(thrust_numeric, na.rm = TRUE), "\n")
cat("Average thrust:", round(mean(thrust_numeric, na.rm = TRUE), 2), "\n")
cat("Median thrust:", median(thrust_numeric, na.rm = TRUE), "\n")
}
# Look for any date columns
date_cols <- names(engine_df)[grepl("DATE", toupper(names(engine_df)))]
if (length(date_cols) > 0) {
cat("\nDate columns found:", paste(date_cols, collapse = ", "), "\n")
for (col in date_cols) {
cat("Sample values for", col, ":\n")
sample_dates <- unique(engine_df[[col]])[1:5]
for (date_val in sample_dates) {
cat(" -", date_val, "\n")
}
}
}
# Clean up extra column if it exists
if ("...7" %in% names(engine_df)) {
cat("\nRemoving empty extra column (...7)\n")
engine_df <- engine_df %>%
select(-`...7`)
}
# Check for missing values
cat("\nMissing value analysis:\n")
missing_summary <- engine_df %>%
summarise_all(~sum(is.na(.) | . == "" | . == " ")) %>%
gather(key = "column", value = "missing_count") %>%
arrange(desc(missing_count))
print(missing_summary)
# Show some sample records with complete data
cat("\nSample complete records:\n")
complete_records <- engine_df %>%
filter(complete.cases(.))
if (nrow(complete_records) > 0) {
cat("Found", nrow(complete_records), "complete records\n")
print(head(complete_records, 3))
} else {
cat("No completely filled records found\n")
}
# Clean up column names - make them MySQL-friendly
original_names <- names(engine_df)
new_names <- original_names %>%
tolower() %>% # Convert to lowercase
gsub("-", "_", .) %>% # Replace hyphens with underscores
gsub(" ", "_", .) %>% # Replace spaces with underscores
gsub("__+", "_", .) %>% # Replace multiple underscores with single
gsub("^_|_$", "", .) %>% # Remove leading/trailing underscores
gsub("^[0-9]", "col_\\1", .) # Prefix numeric column names with 'col_'
# Apply the new names
names(engine_df) <- new_names
cat("Column names tidied for MySQL compatibility:\n")
for (i in seq_along(original_names)) {
cat(sprintf(" %s -> %s\n", original_names[i], new_names[i]))
}
# Function to escape SQL strings and handle NULL values
escape_sql_string <- function(x) {
if (is.na(x) || x == "" || x == " " || x == "NULL") {
return("NULL")
} else {
# Escape single quotes and backslashes
escaped <- gsub("'", "''", x) # Escape single quotes
escaped <- gsub("\\\\", "\\\\\\\\", escaped) # Escape backslashes
return(paste0("'", escaped, "'"))
}
}
# Function to determine appropriate MySQL data types
get_mysql_type <- function(col_name, data) {
# Check if column contains only numeric data
numeric_data <- data[!is.na(data) & data != "" & data != " "]
if (length(numeric_data) > 0) {
is_numeric <- all(grepl("^[0-9.-]+$", numeric_data))
if (is_numeric) {
# Check if it's an integer or decimal
has_decimal <- any(grepl("\\.", numeric_data))
max_length <- max(nchar(numeric_data))
if (has_decimal) {
return(paste0("DECIMAL(", max_length + 2, ",2)"))
} else {
if (max_length <= 3) return("SMALLINT")
if (max_length <= 5) return("INT")
if (max_length <= 10) return("BIGINT")
return(paste0("VARCHAR(", max_length, ")"))
}
}
}
# Check if it's a date column
if (grepl("date", tolower(col_name))) {
return("DATE")
}
# Default to VARCHAR with appropriate length
max_length <- max(nchar(data[!is.na(data) & data != "" & data != " "]), default = 0)
if (max_length == 0) max_length <- 1
return(paste0("VARCHAR(", min(max_length * 2, 255), ")"))
}
# Generate CREATE TABLE statement
cat("\nGenerating SQL CREATE TABLE statement...\n")
# Generate column definitions
column_defs <- character()
for (col in names(engine_df)) {
mysql_type <- get_mysql_type(col, engine_df[[col]])
column_defs <- c(column_defs, paste0(" `", col, "` ", mysql_type))
}
create_table_sql <- paste0(
"-- CREATE TABLE statement for engines data\n",
"-- Generated for MySQL 8.0\n\n",
"DROP TABLE IF EXISTS `engines`;\n",
"CREATE TABLE `engines` (\n",
" `id` INT AUTO_INCREMENT PRIMARY KEY,\n",
paste(column_defs, collapse = ",\n"),
"\n);\n\n"
)
# Generate INSERT statements
cat("Generating INSERT statements...\n")
# Process data in batches to avoid memory issues
batch_size <- 1000
total_rows <- nrow(engine_df)
num_batches <- ceiling(total_rows / batch_size)
# Prepare column names for INSERT
column_names <- paste0("`", names(engine_df), "`", collapse = ", ")
insert_header <- paste0("INSERT INTO `engines` (", column_names, ") VALUES\n")
# Start building the SQL file content
sql_content <- create_table_sql
cat("Processing", total_rows, "rows in", num_batches, "batches...\n")
for (batch_num in 1:num_batches) {
start_row <- (batch_num - 1) * batch_size + 1
end_row <- min(batch_num * batch_size, total_rows)
cat("Processing batch", batch_num, "of", num_batches, "(rows", start_row, "-", end_row, ")\n")
batch_data <- engine_df[start_row:end_row, ]
# Generate VALUES for this batch
values_list <- character()
for (i in 1:nrow(batch_data)) {
row_values <- sapply(batch_data[i, ], escape_sql_string)
values_list <- c(values_list, paste0("(", paste(row_values, collapse = ", "), ")"))
}
# Add batch to SQL content
batch_sql <- paste0(insert_header, paste(values_list, collapse = ",\n"), ";\n\n")
sql_content <- paste0(sql_content, batch_sql)
}
# Write the complete SQL file
sql_output_file <- "engines_import.sql"
cat("Writing SQL file to:", sql_output_file, "\n")
writeLines(sql_content, sql_output_file)
# Also save as CSV for backup
csv_output_file <- paste0(
"engine_clean.csv"
)
cat("Saving CSV backup to:", csv_output_file, "\n")
write_csv(engine_df, csv_output_file)
# Generate summary statistics
cat("\nFiles generated successfully!\n")
cat("SQL file size:", file.info(sql_output_file)$size, "bytes\n")
cat("Total rows:", total_rows, "\n")
cat("Columns:", ncol(engine_df), "\n")
# Show column information
cat("\nColumn information:\n")
for (col in names(engine_df)) {
mysql_type <- get_mysql_type(col, engine_df[[col]])
non_null_count <- sum(!is.na(engine_df[[col]]) & engine_df[[col]] != "" & engine_df[[col]] != " ")
cat(sprintf(" %-20s %-20s (%d non-null values)\n", col, mysql_type, non_null_count))
}
cat("\nTo import into MySQL 8, use:\n")
cat("mysql -u your_username -p your_database < ", sql_output_file, "\n")
cat("\nOr from within MySQL:\n")
cat("SOURCE ", sql_output_file, ";\n")
-- FAA Aircraft Data Import Scripts (Fixed for SQL files)
-- This version uses SQL import files from /data/clean
-- Database: faa_aircraft_four_db
-- Source files from: /data/clean
-- Create the database
CREATE DATABASE IF NOT EXISTS faa_aircraft_four_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
USE faa_aircraft_four_db;
-- Import aircraft_reference_import.sql (Aircraft Reference)
SOURCE aircraft_reference_import.sql;
-- Import engines_import.sql (Engine Specifications)
SOURCE engines_import.sql;
-- Import dealers_import.sql (Aircraft Dealers)
SOURCE dealers_import.sql;
-- Import aircraft_master_import.sql (Main Aircraft Registry)
SOURCE aircraft_master_import.sql;
-- Import deregistered_aircraft_import.sql (Deregistered Aircraft)
SOURCE deregistered_aircraft_import.sql;
-- Import documentation_index_import.sql (Documentation Index)
SOURCE documentation_index_import.sql;
-- Import reserved_numbers_import.sql (Reserved N-Numbers)
SOURCE reserved_numbers_import.sql;
-- Verify import results
SELECT 'aircraft_reference' as table_name, COUNT(*) as record_count FROM aircraft_reference
UNION ALL
SELECT 'engines', COUNT(*) FROM engines
UNION ALL
SELECT 'dealers', COUNT(*) FROM dealers
UNION ALL
SELECT 'aircraft_master', COUNT(*) FROM aircraft_master
UNION ALL
SELECT 'deregistered_aircraft', COUNT(*) FROM deregistered_aircraft
UNION ALL
SELECT 'documentation_index', COUNT(*) FROM documentation_index
UNION ALL
SELECT 'reserved_numbers', COUNT(*) FROM reserved_numbers;
SELECT 'Import completed successfully!' as status;
And then indexes were applied to the fields in each table using
-- Add indexes to FAA Aircraft Database for better performance
-- Updated for faa_aircraft_four_db with correct field names
USE faa_aircraft_four_db;
-- Indexes for aircraft_master table
CREATE INDEX idx_n_number ON aircraft_master(n_number);
CREATE INDEX idx_serial_number ON aircraft_master(serial_number);
CREATE INDEX idx_mfr_mdl_code ON aircraft_master(mfr_mdl_code);
CREATE INDEX idx_state ON aircraft_master(state);
CREATE INDEX idx_name ON aircraft_master(name);
CREATE INDEX idx_year_mfr ON aircraft_master(year_mfr);
CREATE INDEX idx_city ON aircraft_master(city);
CREATE INDEX idx_country ON aircraft_master(country);
CREATE INDEX idx_type_aircraft ON aircraft_master(type_aircraft);
CREATE INDEX idx_type_engine ON aircraft_master(type_engine);
CREATE INDEX idx_status_code ON aircraft_master(status_code);
-- Indexes for aircraft_reference table
CREATE INDEX idx_mfr ON aircraft_reference(mfr);
CREATE INDEX idx_model ON aircraft_reference(model);
CREATE INDEX idx_code ON aircraft_reference(code);
-- Indexes for engines table
CREATE INDEX idx_code ON engines(code);
CREATE INDEX idx_mfr ON engines(mfr);
CREATE INDEX idx_model ON engines(model);
CREATE INDEX idx_type ON engines(type);
-- Indexes for dealers table
CREATE INDEX idx_certificate_number ON dealers(certificate_number);
CREATE INDEX idx_name ON dealers(name);
CREATE INDEX idx_city ON dealers(city);
CREATE INDEX idx_state_abbrev ON dealers(state_abbrev);
-- Indexes for deregistered_aircraft table
CREATE INDEX idx_n_number ON deregistered_aircraft(n_number);
CREATE INDEX idx_serial_number ON deregistered_aircraft(serial_number);
CREATE INDEX idx_mfr_mdl_code ON deregistered_aircraft(mfr_mdl_code);
CREATE INDEX idx_name ON deregistered_aircraft(name);
CREATE INDEX idx_city_mail ON deregistered_aircraft(city_mail);
CREATE INDEX idx_state_abbrev_mail ON deregistered_aircraft(state_abbrev_mail);
CREATE INDEX idx_year_mfr ON deregistered_aircraft(year_mfr);
-- Indexes for documentation_index table
CREATE INDEX idx_collateral ON documentation_index(collateral);
CREATE INDEX idx_doc_id ON documentation_index(doc_id);
CREATE INDEX idx_serial_id ON documentation_index(serial_id);
CREATE INDEX idx_doc_type ON documentation_index(doc_type);
-- Indexes for reserved_numbers table
CREATE INDEX idx_n_number ON reserved_numbers(n_number);
CREATE INDEX idx_registrant ON reserved_numbers(registrant);
CREATE INDEX idx_city ON reserved_numbers(city);
CREATE INDEX idx_state ON reserved_numbers(state);
-- Show all indexes created
SHOW INDEX FROM aircraft_master;
SHOW INDEX FROM aircraft_reference;
SHOW INDEX FROM engines;
SHOW INDEX FROM dealers;
SHOW INDEX FROM deregistered_aircraft;
SHOW INDEX FROM documentation_index;
SHOW INDEX FROM reserved_numbers;
SELECT 'All indexes created successfully!' as status;
This section presents a comprehensive analysis of the FAA aircraft registration database using SQL queries and data visualizations. The analysis covers database structure, key statistics, and insights derived from the data.
All queries were executed against a local MySQL 8.0 database containing the complete FAA aircraft registration dataset. Results are presented with both raw data and visual interpretations where applicable.
The FAA aircraft database contains 7 main tables with comprehensive aircraft registration and reference data:
Active Database:
faa_aircraft_four_db
-- Table overview with row counts and storage information
SELECT
TABLE_NAME,
TABLE_TYPE,
ENGINE,
TABLE_ROWS,
ROUND(DATA_LENGTH/1024/1024, 2) as DATA_SIZE_MB,
ROUND(INDEX_LENGTH/1024/1024, 2) as INDEX_SIZE_MB
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE()
ORDER BY TABLE_ROWS DESC;| Table Name | Type | Engine | Rows | Data Size (MB) | Index Size (MB) |
|---|---|---|---|---|---|
| deregistered_aircraft | BASE TABLE | InnoDB | 359,778 | 61.6 | 0.0 |
| aircraft_master | BASE TABLE | InnoDB | 302,049 | 60.6 | 0.0 |
| reserved_numbers | BASE TABLE | InnoDB | 128,292 | 14.5 | 0.0 |
| aircraft_reference | BASE TABLE | InnoDB | 93,503 | 8.5 | 0.0 |
| dealers | BASE TABLE | InnoDB | 11,743 | 1.5 | 0.0 |
| documentation_index | BASE TABLE | InnoDB | 9,715 | 1.5 | 0.0 |
| engines | BASE TABLE | InnoDB | 4,708 | 0.3 | 0.0 |
mysql> SELECT -> TABLE_NAME, -> COLUMN_NAME, -> INDEX_NAME, -> NON_UNIQUE, -> SEQ_IN_INDEX -> FROM information_schema.STATISTICS -> WHERE TABLE_SCHEMA = DATABASE() -> ORDER BY TABLE_NAME, INDEX_NAME, SEQ_IN_INDEX;
+-----------------------+--------------------+------------------------+------------+--------------+
|TABLE_NAME | COLUMN_NAME | INDEX_NAME | NON_UNIQUE | SEQ_IN_INDEX |
+-----------------------+--------------------+------------------------+------------+--------------+
|aircraft_master | city | idx_city | 1 | 1 |
|aircraft_master | country | idx_country | 1 | 1 |
|aircraft_master | mfr_mdl_code | idx_mfr_mdl_code | 1 | 1 |
|aircraft_master | n_number | idx_n_number | 1 | 1 |
|aircraft_master | name | idx_name | 1 | 1 |
|aircraft_master | serial_number | idx_serial_number | 1 | 1 |
|aircraft_master | state | idx_state | 1 | 1 |
|aircraft_master | status_code | idx_status_code | 1 | 1 |
|aircraft_master | type_aircraft | idx_type_aircraft | 1 | 1 |
|aircraft_master | type_engine | idx_type_engine | 1 | 1 |
|aircraft_master | year_mfr | idx_year_mfr | 1 | 1 |
|aircraft_master | id | PRIMARY | 0 | 1 |
|aircraft_reference | code | idx_code | 1 | 1 |
|aircraft_reference | mfr | idx_mfr | 1 | 1 |
|aircraft_reference | model | idx_model | 1 | 1 |
|aircraft_reference | id | PRIMARY | 0 | 1 |
|dealers | certificate_number | idx_certificate_number | 1 | 1 |
|dealers | city | idx_city | 1 | 1 |
|dealers | name | idx_name | 1 | 1 |
|dealers | state_abbrev | idx_state_abbrev | 1 | 1 |
|dealers | id | PRIMARY | 0 | 1 |
|deregistered_aircraft | city_mail | idx_city_mail | 1 | 1 |
|deregistered_aircraft | mfr_mdl_code | idx_mfr_mdl_code | 1 | 1 |
|deregistered_aircraft | n_number | idx_n_number | 1 | 1 |
|deregistered_aircraft | name | idx_name | 1 | 1 |
|deregistered_aircraft | serial_number | idx_serial_number | 1 | 1 |
|deregistered_aircraft | state_abbrev_mail | idx_state_abbrev_mail | 1 | 1 |
|deregistered_aircraft | year_mfr | idx_year_mfr | 1 | 1 |
|deregistered_aircraft | id | PRIMARY | 0 | 1 |
|documentation_index | collateral | idx_collateral | 1 | 1 |
|documentation_index | doc_id | idx_doc_id | 1 | 1 |
|documentation_index | doc_type | idx_doc_type | 1 | 1 |
|documentation_index | serial_id | idx_serial_id | 1 | 1 |
|documentation_index | id | PRIMARY | 0 | 1 |
|engines | code | idx_code | 1 | 1 |
|engines | mfr | idx_mfr | 1 | 1 |
|engines | model | idx_model | 1 | 1 |
|engines | type | idx_type | 1 | 1 |
|engines | id | PRIMARY | 0 | 1 |
|reserved_numbers | city | idx_city | 1 | 1 |
|reserved_numbers | n_number | idx_n_number | 1 | 1 |
|reserved_numbers | registrant | idx_registrant | 1 | 1 |
|reserved_numbers | state | idx_state | 1 | 1 |
|reserved_numbers | id | PRIMARY | 0 | 1 |
+-----------------------+--------------------+------------------------+------------+--------------+
44 rows in set (0.01 sec)
mysql> SHOW TABLE STATUS\G;
*************************** 1. row ***************************
Name: aircraft_master
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 302049
Avg_row_length: 210
Data_length: 63537152
Max_data_length: 0
Index_length: 0
Data_free: 4194304
Auto_increment: 306404
Create_time: 2025-09-14 17:01:57
Update_time: 2025-09-14 16:38:46
Check_time: NULL
Collation: utf8mb4_unicode_ci
Checksum: NULL
Create_options:
Comment:
*************************** 2. row ***************************
Name: aircraft_reference
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 93503
Avg_row_length: 95
Data_length: 8929280
Max_data_length: 0
Index_length: 0
Data_free: 2097152
Auto_increment: 93126
Create_time: 2025-09-14 17:01:57
Update_time: 2025-09-14 16:38:42
Check_time: NULL
Collation: utf8mb4_unicode_ci
Checksum: NULL
Create_options:
Comment:
*************************** 3. row ***************************
Name: dealers
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 11743
Avg_row_length: 135
Data_length: 1589248
Max_data_length: 0
Index_length: 0
Data_free: 3145728
Auto_increment: 12193
Create_time: 2025-09-14 17:01:57
Update_time: 2025-09-14 16:38:42
Check_time: NULL
Collation: utf8mb4_unicode_ci
Checksum: NULL
Create_options:
Comment:
*************************** 4. row ***************************
Name: deregistered_aircraft
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 359778
Avg_row_length: 179
Data_length: 64585728
Max_data_length: 0
Index_length: 0
Data_free: 2097152
Auto_increment: 380963
Create_time: 2025-09-14 17:01:59
Update_time: 2025-09-14 16:38:52
Check_time: NULL
Collation: utf8mb4_unicode_ci
Checksum: NULL
Create_options:
Comment:
*************************** 5. row ***************************
Name: documentation_index
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 9715
Avg_row_length: 163
Data_length: 1589248
Max_data_length: 0
Index_length: 0
Data_free: 3145728
Auto_increment: 9541
Create_time: 2025-09-14 17:01:59
Update_time: 2025-09-14 16:38:52
Check_time: NULL
Collation: utf8mb4_unicode_ci
Checksum: NULL
Create_options:
Comment:
*************************** 6. row ***************************
Name: engines
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 4708
Avg_row_length: 73
Data_length: 344064
Max_data_length: 0
Index_length: 0
Data_free: 0
Auto_increment: 4729
Create_time: 2025-09-14 17:01:57
Update_time: 2025-09-14 16:38:42
Check_time: NULL
Collation: utf8mb4_unicode_ci
Checksum: NULL
Create_options:
Comment:
*************************** 7. row ***************************
Name: reserved_numbers
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 128292
Avg_row_length: 118
Data_length: 15220736
Max_data_length: 0
Index_length: 0
Data_free: 5242880
Auto_increment: 128308
Create_time: 2025-09-14 17:01:59
Update_time: 2025-09-14 16:38:52
Check_time: NULL
Collation: utf8mb4_unicode_ci
Checksum: NULL
Create_options:
Comment:
7 rows in set (0.00 sec)
mysql> SELECT
TABLE_NAME as 'Table Name',
ENGINE as 'Engine',
ROUND(DATA_LENGTH / 1024 / 1024, 2) AS 'Data Size (MB)',
ROUND(INDEX_LENGTH / 1024 / 1024, 2) AS 'Index Size (MB)',
ROUND((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024, 2) AS 'Total Size (MB)',
TABLE_ROWS as 'Approx Rows',
ROUND((DATA_LENGTH + INDEX_LENGTH) / TABLE_ROWS, 0) AS 'Bytes per Row',
CREATE_TIME as 'Created',
UPDATE_TIME as 'Last Updated'
FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_SCHEMA = 'faa_aircraft_db'
ORDER BY (DATA_LENGTH + INDEX_LENGTH) DESC\G;
************************** 1. row ***************************
Table Name: aircraft_master
Engine: InnoDB
Data Size (MB): 73.63
Index Size (MB): 77.70
Total Size (MB): 151.33
Approx Rows: 300490
Bytes per Row: 528
Created: 2025-09-10 18:42:19
Last Updated: NULL
*************************** 2. row ***************************
Table Name: deregistered_aircraft
Engine: InnoDB
Data Size (MB): 76.63
Index Size (MB): 0.00
Total Size (MB): 76.63
Approx Rows: 371163
Bytes per Row: 216
Created: 2025-09-10 20:57:54
Last Updated: NULL
*************************** 3. row ***************************
Table Name: reserved_numbers
Engine: InnoDB
Data Size (MB): 18.55
Index Size (MB): 0.00
Total Size (MB): 18.55
Approx Rows: 121334
Bytes per Row: 160
Created: 2025-09-10 00:44:58
Last Updated: NULL
*************************** 4. row ***************************
Table Name: aircraft_reference
Engine: InnoDB
Data Size (MB): 11.52
Index Size (MB): 0.00
Total Size (MB): 11.52
Approx Rows: 92809
Bytes per Row: 130
Created: 2025-09-10 00:44:39
Last Updated: NULL
*************************** 5. row ***************************
Table Name: dealers
Engine: InnoDB
Data Size (MB): 2.52
Index Size (MB): 0.00
Total Size (MB): 2.52
Approx Rows: 12030
Bytes per Row: 219
Created: 2025-09-10 00:44:40
Last Updated: NULL
*************************** 6. row ***************************
Table Name: documentation_index
Engine: InnoDB
Data Size (MB): 2.52
Index Size (MB): 0.00
Total Size (MB): 2.52
Approx Rows: 22064
Bytes per Row: 120
Created: 2025-09-10 00:44:58
Last Updated: NULL
*************************** 7. row ***************************
Table Name: engines
Engine: InnoDB
Data Size (MB): 0.48
Index Size (MB): 0.00
Total Size (MB): 0.48
Approx Rows: 4602
Bytes per Row: 110
Created: 2025-09-10 00:44:39
Last Updated: NULL
7 rows in set (0.01 sec)
mysql> SELECT TABLE_NAME as ‘Table Name’, COUNT() as ‘Column Count’ FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_SCHEMA = ‘faa_aircraft_db’ GROUP BY TABLE_NAME ORDER BY COUNT() DESC;
+-----------------------+--------------+
|Table Name | Column Count |
+-----------------------+--------------+
|deregistered_aircraft | 40 |
|aircraft_master | 35 |
|dealers | 26 |
|aircraft_reference | 14 |
|reserved_numbers | 13 |
|documentation_index | 10 |
|engines | 7 |
+-----------------------+--------------+
7 rows in set (0.01 sec)
mysql> SELECT ‘TOTAL DATABASE SUMMARY’ as ‘Metric’, ROUND(SUM((DATA_LENGTH + INDEX_LENGTH) / 1024 / 1024), 2) AS ‘Total Size (MB)’, SUM(TABLE_ROWS) as ‘Total Approx Rows’, COUNT(*) as ‘Total Tables’ FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = ‘faa_aircraft_four_db’;
+------------------------+-----------------+-------------------+--------------+
|Metric | Total Size (MB) | Total Approx Rows | Total Tables |
+------------------------+-----------------+-------------------+--------------+
|TOTAL DATABASE SUMMARY | 148.58 | 909788 | 7 |
+------------------------+-----------------+-------------------+--------------+
1 row in set (0.00 sec)
The aircraft_master table is the core of the FAA
database, containing detailed registration information for all currently
registered aircraft in the United States.
mysql> DESCRIBE aircraft_master;
+------------------+--------------+------+-----+---------+----------------+
|Field | Type | Null | Key | Default | Extra |
+------------------+--------------+------+-----+---------+----------------+
|id | int | NO | PRI | NULL | auto_increment |
|n_number | varchar(10) | YES | MUL | NULL | |
|serial_number | varchar(60) | YES | MUL | NULL | |
|mfr_mdl_code | varchar(14) | YES | MUL | NULL | |
|eng_mfr_mdl | int | YES | | NULL | |
|year_mfr | int | YES | MUL | NULL | |
|type_registrant | smallint | YES | | NULL | |
|name | varchar(100) | YES | MUL | NULL | |
|street | varchar(66) | YES | | NULL | |
|street2 | varchar(66) | YES | | NULL | |
|city | varchar(36) | YES | MUL | NULL | |
|state | varchar(4) | YES | MUL | NULL | |
|zip_code | varchar(20) | YES | | NULL | |
|region | varchar(2) | YES | | NULL | |
|county | smallint | YES | | NULL | |
|country | varchar(4) | YES | MUL | NULL | |
|last_action_date | bigint | YES | | NULL | |
|cert_issue_date | bigint | YES | | NULL | |
|certification | varchar(20) | YES | | NULL | |
|type_aircraft | varchar(2) | YES | MUL | NULL | |
|type_engine | smallint | YES | MUL | NULL | |
|status_code | varchar(4) | YES | MUL | NULL | |
|mode_s_code | bigint | YES | | NULL | |
|fract_owner | varchar(2) | YES | | NULL | |
|air_worth_date | bigint | YES | | NULL | |
|other_names(1) | varchar(100) | YES | | NULL | |
|other_names(2) | varchar(98) | YES | | NULL | |
|other_names(3) | varchar(98) | YES | | NULL | |
|other_names(4) | varchar(88) | YES | | NULL | |
|other_names(5) | varchar(94) | YES | | NULL | |
|expiration_date | bigint | YES | | NULL | |
|unique_id | bigint | YES | | NULL | |
|kit_mfr | varchar(60) | YES | | NULL | |
|kit_model | varchar(40) | YES | | NULL | |
|mode_s_code_hex | varchar(12) | YES | | NULL | |
|...35 | varchar(2) | YES | | NULL | |
+------------------+--------------+------+-----+---------+----------------+
36 rows in set (0.00 sec)
mysql> SHOW INDEX FROM aircraft_master\G
*************************** 1. row ***************************
Table: aircraft_master
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: id
Collation: A
Cardinality: 302049
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 2. row ***************************
Table: aircraft_master
Non_unique: 1
Key_name: idx_n_number
Seq_in_index: 1
Column_name: n_number
Collation: A
Cardinality: 302049
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 3. row *************************** and so on
-- Top 10 states by aircraft registration count
SELECT
state,
COUNT(*) as aircraft_count,
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM aircraft_master), 2) as percentage
FROM aircraft_master
WHERE state IS NOT NULL
GROUP BY state
ORDER BY aircraft_count DESC
LIMIT 10;| State | Aircraft Count | Percentage of Total |
|---|---|---|
| TX | 28,614 | 9.47% |
| CA | 25,123 | 8.32% |
| FL | 21,217 | 7.02% |
| DE | 10,962 | 3.63% |
| WA | 10,103 | 3.35% |
| AK | 9,076 | 3.01% |
| GA | 8,597 | 2.85% |
| UT | 8,468 | 2.80% |
| AZ | 8,303 | 2.75% |
| OH | 8,113 | 2.69% |
-- Top aircraft manufacturers by model count
SELECT
mfr as manufacturer,
COUNT(*) as model_count,
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM aircraft_reference), 2) as percentage
FROM aircraft_reference
GROUP BY mfr
ORDER BY model_count DESC
LIMIT 10;| Manufacturer | Model Count | Percentage |
|---|---|---|
| BOEING | 1,541 | 1.65% |
| CESSNA | 419 | 0.45% |
| BEECH | 336 | 0.36% |
| PIPER | 261 | 0.28% |
| DOUGLAS | 240 | 0.26% |
| LOCKHEED | 221 | 0.24% |
| SIKORSKY | 197 | 0.21% |
| BELL | 161 | 0.17% |
| DJI | 159 | 0.17% |
| DEHAVILLAND | 151 | 0.16% |
mysql> SELECT n_number AS ‘N-Number’, name AS ‘Owner’, city AS ‘City’, state AS ‘State’, year_mfr AS ‘Year’, mfr_mdl_code AS ‘Model_Code’ FROM aircraft_master WHERE n_number = ‘10004’;
+----------+--------------+------------+-------+------+------------+
|N-Number | Owner | City | State | Year | Model_Code |
+----------+--------------+------------+-------+------+------------+
|10004 | ETOS AIR LLC | NEW LONDON | TX | NULL | 2072738 |
+----------+--------------+------------+-------+------+------------+
1 row in set (0.00 sec)
mysql> SELECT * FROM aircraft_master WHERE n_number = '10004'\G
*************************** 1. row ***************************
id: 4
n_number: 10004
serial_number: T18208245
mfr_mdl_code: 2072738
eng_mfr_mdl: NULL
year_mfr: NULL
type_registrant: 7
name: ETOS AIR LLC
street: PO BOX 288
street2: NULL
city: NEW LONDON
state: TX
zip_code: 756820288
region: 2
county: 401
country: US
last_action_date: 20230722
cert_issue_date: 20130312
certification: NULL
type_aircraft: 4
type_engine: 2
status_code: V
mode_s_code: 50003451
fract_owner: NULL
air_worth_date: NULL
other_names(1): NULL
other_names(2): NULL
other_names(3): NULL
other_names(4): NULL
other_names(5): NULL
expiration_date: 20290331
unique_id: 102879
kit_mfr: NULL
kit_model: NULL
mode_s_code_hex: A00729
...35: NULL
1 row in set (0.00 sec)
mysql> SELECT n_number AS ‘N-Number’, name AS ‘Owner’, city AS ‘City’, state AS ‘State’, year_mfr AS ‘Year’, mfr_mdl_code AS ‘Model_Code’ FROM aircraft_master WHERE n_number IS NOT NULL LIMIT 5;
+----------+------------------------------+------------+-------+------+------------+
|N-Number | Owner | City | State | Year | Model_Code |
+----------+------------------------------+------------+-------+------+------------+
|100 | BENE MARY D | KETCHUM | OK | 1940 | 7100510 |
|10000 | 9AT LLC | NASHVILLE | TN | NULL | 2130004 |
|10001 | STOOS ROBERT A | LAKELAND | FL | 1928 | 9601202 |
|10004 | ETOS AIR LLC | NEW LONDON | TX | NULL | 2072738 |
|10006 | COUTCHES ROBERT HERCULES DBA | LIVERMORE | CA | 1955 | 1152020 |
+----------+------------------------------+------------+-------+------+------------+
5 rows in set (0.00 sec)
-- Aircraft registrations by manufacturing year (last 12 years)
SELECT
year_mfr as manufacturing_year,
COUNT(*) as aircraft_count,
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM aircraft_master WHERE year_mfr >= 2014), 2) as percentage
FROM aircraft_master
WHERE year_mfr >= 2014
GROUP BY year_mfr
ORDER BY year_mfr DESC;| Manufacturing Year | Aircraft Count | Percentage |
|---|---|---|
| 2025 | 2,139 | 6.8% |
| 2024 | 3,800 | 12.1% |
| 2023 | 3,884 | 12.4% |
| 2022 | 3,352 | 10.7% |
| 2021 | 2,941 | 9.4% |
| 2020 | 2,701 | 8.6% |
| 2019 | 3,109 | 9.9% |
| 2018 | 2,877 | 9.2% |
| 2017 | 2,823 | 9.0% |
| 2016 | 2,780 | 8.9% |
| 2015 | 2,913 | 9.3% |
| 2014 | 2,858 | 9.1% |
mysql> SELECT country, COUNT(*) as count FROM aircraft_master GROUP BY country ORDER BY count DESC;
+---------+--------+
|country | count |
+---------+--------+
|US | 301955 |
|NULL | 2376 |
|GB | 761 |
|RQ | 482 |
|DE | 331 |
|AT | 100 |
|VI | 94 |
|GU | 65 |
|CA | 47 |
|MP | 31 |
|CH | 17 |
|MX | 12 |
|IE | 11 |
|FR | 9 |
|BS | 8 |
|PL | 8 |
|SA | 7 |
|HR | 7 |
|PA | 7 |
|GR | 6 |
|TH | 5 |
|BE | 5 |
|AU | 4 |
|JP | 4 |
|NZ | 4 |
|DO | 3 |
|KY | 3 |
|TC | 3 |
|SE | 2 |
|ES | 2 |
|UA | 2 |
|DK | 2 |
|PH | 2 |
|ZA | 2 |
|JE | 2 |
|NL | 2 |
|MY | 2 |
|IT | 1 |
|MD | 1 |
|NF | 1 |
|NG | 1 |
|LV | 1 |
|LU | 1 |
|KE | 1 |
|IL | 1 |
|HK | 1 |
|PW | 1 |
|GY | 1 |
|FM | 1 |
|FI | 1 |
|BW | 1 |
|BR | 1 |
|AS | 1 |
|AN | 1 |
|AI | 1 |
|AG | 1 |
|ZW | 1 |
+---------+--------+
57 rows in set (0.06 sec)
This query groups aircraft by decade (e.g., “2020s”, “2010s”, “1990s”) and counts how many aircraft were manufactured in each decade.
mysql> SELECT decade, COUNT() as count FROM ( SELECT CONCAT(FLOOR(year_mfr/10)10, ‘s’) as decade FROM aircraft_master WHERE year_mfr IS NOT NULL ) as decades GROUP BY decade ORDER BY decade DESC;
+--------+-------+
|decade | count |
+--------+-------+
|2020s | 18817 |
|2010s | 27299 |
|2000s | 36620 |
|1990s | 17804 |
|1980s | 17763 |
|1970s | 49584 |
|1960s | 37371 |
|1950s | 16148 |
|1940s | 20882 |
|1930s | 1599 |
|1920s | 405 |
|1910s | 32 |
|1900s | 1 |
|0s | 151 |
+--------+-------+
14 rows in set (0.11 sec)
Description: Counts of each Type Aircraft code present in
aircraft_master.
mysql> SELECT type_aircraft, COUNT(*) AS count FROM aircraft_master WHERE type_aircraft IS NOT NULL GROUP BY type_aircraft ORDER BY type_aircraft;
+---------------+--------+
|type_aircraft | count |
+---------------+--------+
|1 | 4842 |
|2 | 5179 |
|3 | 49 |
|4 | 218584 |
|5 | 48847 |
|6 | 24588 |
|7 | 1046 |
|8 | 1902 |
|9 | 376 |
|H | 969 |
|O | 21 |
+---------------+--------+
11 rows in set (0.06 sec)
mysql> SELECT mfr AS ‘Manufacturer’, model AS ‘Model’, type_acft AS ‘Type’, no_eng AS ‘Engines’, no_seats AS ‘Seats’ FROM aircraft_reference WHERE mfr IS NOT NULL LIMIT 5;
+--------------------------+-------------------+------+---------+-------+
|Manufacturer | Model | Type | Engines | Seats |
+--------------------------+-------------------+------+---------+-------+
|101 FLYING ASSOC INC | THORP T-18 | 4 | 1 | 2 |
|107.5 FLYING CORPORATION | ONE DESIGN DR 107 | 4 | 1 | 1 |
|131MH LLC | CCX-1865 | 4 | 1 | 2 |
|17633 INC | 162F | 6 | 1 | 2 |
|177MF LLC | PITTS MODEL 12 | 4 | 1 | 2 |
+--------------------------+-------------------+------+---------+-------+
5 rows in set (0.01 sec)
Description: Retrieves specifications for the aircraft model associated with serial number 42626.
mysql> SELECT ar.code, ar.mfr, ar.model, ar.type_acft, ar.ac_cat, ar.no_eng, ar.ac_weight, ar.no_seats, ar.speed FROM aircraft_reference ar WHERE ar.code = (SELECT mfr_mdl_code FROM aircraft_master WHERE serial_number = ‘42626’)
************************** 1. row ***************************
code: 13845FZ
mfr: BOEING
model: 737-8
type_acft: 5
ac_cat: 1
no_eng: 2
ac_weight: CLASS 3
no_seats: 175
speed: 0
1 row in set (0.00 sec)
mysql> SELECT mfr AS ‘Manufacturer’, model AS ‘Model’, type AS ‘Type’, horsepower AS ‘HP’, thrust AS ‘Thrust’ FROM engines WHERE mfr IS NOT NULL LIMIT 5;
+--------------+---------------+------+------+--------+
|Manufacturer | Model | Type | HP | Thrust |
+--------------+---------------+------+------+--------+
|NONE | NONE | 0 | 0 | 0 |
|A.C.E. | HIDR MARK III | 1 | 95 | 0 |
|A.C.E. | UPRI MARK III | 1 | 100 | 0 |
|AEROMOMENT | AM13 SERIES | 8 | 100 | 0 |
|AEROMOMENT | AM15 SERIES | 8 | 117 | 0 |
+--------------+---------------+------+------+--------+
5 rows in set (0.00 sec)
mysql> SELECT CASE type WHEN ‘0’ THEN ‘None’ WHEN ‘1’ THEN ‘Reciprocating’ WHEN ‘2’ THEN ‘Turbo-prop’ WHEN ‘3’ THEN ‘Turbo-shaft’ WHEN ‘4’ THEN ‘Turbo-jet’ WHEN ‘5’ THEN ‘Turbo-fan’ WHEN ‘6’ THEN ‘Ramjet’ WHEN ‘7’ THEN ‘2 Cycle’ WHEN ‘8’ THEN ‘4 Cycle’ WHEN ‘9’ THEN ‘Unknown’ WHEN ‘10’ THEN ‘Electric’ WHEN ‘11’ THEN ‘Rotary’ ELSE CONCAT(‘Type’, type) END AS ‘Engine_Type’, COUNT(*) AS ‘Count’ FROM engines WHERE type IS NOT NULL GROUP BY type ORDER BY Count DESC;
+---------------+-------+
|Engine_Type | Count |
+---------------+-------+
|Reciprocating | 2398 |
|Turbo-prop | 749 |
|Turbo-fan | 712 |
|Turbo-shaft | 397 |
|Turbo-jet | 191 |
|4 Cycle | 167 |
|2 Cycle | 70 |
|Electric | 37 |
|Rotary | 4 |
|None | 1 |
|Unknown | 1 |
+---------------+-------+
11 rows in set (0.00 sec)
Description: Engine manufacturer/model, type code, horsepower/thrust for the engine code seen on the matched aircraft.
mysql> SELECT er.code, er.mfr, er.model, er.type, er.horsepower, er.thrust FROM engines er WHERE er.code = ‘13120’;
+-------+----------+---------------+------+------------+--------+
|code | mfr | model | type | horsepower | thrust |
+-------+----------+---------------+------+------------+--------+
|13120 | CFM INTL | LEAP-1B28 SER | 5 | 0 | 29317 |
+-------+----------+---------------+------+------------+--------+
1 row in set (0.00 sec)
mysql> SELECT * FROM engines WHERE mfr LIKE ‘%GE%’ ORDER BY horsepower DESC LIMIT 10;
+------+-------+------+--------------+------+------------+--------+
|id | code | mfr | model | type | horsepower | thrust |
+------+-------+------+--------------+------+------------+--------+
|1397 | 30040 | GE | YF-120 | 5 | 5000 | 0 |
|1536 | 30179 | GE | T64-GE-419 | 3 | 4750 | 0 |
|1517 | 30160 | GE | T64-GE-416 | 3 | 4380 | 0 |
|1604 | 31132 | GE | J-79-15A | 4 | 4000 | 0 |
|1516 | 30159 | GE | T64-GE-413 | 3 | 3925 | 0 |
|1376 | 30019 | GE | CT64-820-4 | 2 | 3133 | 0 |
|1369 | 30012 | GE | T64-GE-10 | 3 | 2850 | 0 |
|1363 | 30006 | GE | CJ610-SER | 4 | 2700 | 0 |
|1540 | 30183 | GE | CT7-8A7 | 3 | 2685 | 0 |
|1547 | 30190 | GE | YT706-GE-700 | 3 | 2638 | 0 |
+------+-------+------+--------------+------+------------+--------+
10 rows in set (0.01 sec)
mysql> SELECT mfr, COUNT(*) as engine_count FROM engines GROUP BY mfr ORDER BY engine_count DESC LIMIT 10;
+------------+--------------+
|mfr | engine_count |
+------------+--------------+
|LYCOMING | 868 |
|CONT MOTOR | 408 |
|P & W | 352 |
|ROLLS-ROYC | 300 |
|WRIGHT | 282 |
|GE | 216 |
|P&W CANADA | 203 |
|HONEYWELL | 197 |
|ALLIEDSIGN | 153 |
|GARRETT | 120 |
+------------+--------------+
10 rows in set (0.00 sec)
SELECT mfr, model, horsepower FROM engines WHERE horsepower > 1000 ORDER BY horsepower DESC LIMIT 20;
+------------+---------------+------------+
|mfr | model | horsepower |
+------------+---------------+------------+
|ROLLS | RB3043/PRL700 | 18250 |
|ROLLS-ROYC | FLYGMTR RM6C | 17500 |
|ROLLS-ROYC | TRENT 800 | 14500 |
|ROLL-ROYC | TAY 620-15 | 13850 |
|ROLLS-ROYC | MK511-14 | 11400 |
|ROLLS-ROYC | SPEY 555-15P | 9900 |
|P&W | T34 SERIES | 7500 |
|AVRO | ALF 507-1F | 7500 |
|LYCOMING | ALF-502 SER. | 7500 |
|HONEYWELL | ALF 502 SER | 7500 |
|LYCOMING | AL503 SER | 7500 |
|KLIMOV | VK-1A | 5950 |
|ROLLS-ROYC | TYNE 515 | 5521 |
|ALLIEDSIGN | ATF3-6 | 5440 |
|HONEYWELL | ATF3-6 | 5440 |
|GARRETT | ATF3-6 | 5440 |
|HONEYWELL | ATF3-6A | 5440 |
|GARRETT | ATF3-6A | 5440 |
|ALLIEDSIGN | ATF3-6A | 5440 |
|ROLLS-ROYC | TYNE 512 | 5344 |
+------------+---------------+------------+
20 rows in set (0.00 sec)
– Jet engines (turbo-jet and turbo-fan) SELECT mfr, model, type, thrust FROM engines WHERE type IN (4, 5) ORDER BY thrust DESC LIMIT 20;
+------------+---------------+------+--------+
|mfr | model | type | thrust |
+------------+---------------+------+--------+
|GE | GE90-115B | 5 | 115540 |
|GE | GE90-113B | 5 | 113530 |
|GE | GE90-110B1 | 5 | 110760 |
|GE | GE9X SERIES | 5 | 105000 |
|P & W | PW4098 | 5 | 99040 |
|GE | GE90-94B | 5 | 97300 |
|GE | GE90-90B | 5 | 94000 |
|ROLLS-ROYC | RB211 895-17 | 5 | 92940 |
|P & W | PW4090D | 5 | 91790 |
|P & W | PW4090 | 5 | 91790 |
|P & W | PW4090-3 | 5 | 91790 |
|ROLLS-ROYC | RB211-892-17 | 5 | 91450 |
|ROLLS-ROYC | RB211 892B-17 | 5 | 91450 |
|ROLLS-ROY | TRENT 892-17 | 5 | 91450 |
|ROLLS-ROYC | TRENT-892 | 5 | 91450 |
|GE | GE90-85B | 5 | 88870 |
|P & W | PW4084 | 5 | 86760 |
|P & W | PW4084D | 5 | 86760 |
|ROLLS-ROYC | RB211 884-17 | 5 | 85430 |
|ROLLS-ROYC | RB211 884B-17 | 5 | 85430 |
+------------+---------------+------+--------+
20 rows in set (0.01 sec)
mysql> SELECT name AS ‘Dealer_Name’, city AS ‘City’, state_abbrev AS ‘State’, certificate_number AS ‘Cert_Number’ FROM dealers WHERE name IS NOT NULL LIMIT 5;
+---------------------------+------------------+-------+-------------+
|Dealer_Name | City | State | Cert_Number |
+---------------------------+------------------+-------+-------------+
|002050721TION LLC | NULL | NULL | DCN3011 |
|007 ARKNASAS AVIATION LLC | NULL | NULL | DCN0566 |
|007 AVIATION GROUP LLC | PORT SAINT LUCIE | FL | D006431 |
|007 DUSTING INC | LA JUNTA | CO | D005490 |
|1 FLIGHT UP LLC | VACAVILLE | CA | 01-0463 |
+---------------------------+------------------+-------+-------------+
5 rows in set (0.00 sec)
mysql> SELECT am.n_number AS ‘N-Number’, am.name AS ‘Owner’, am.city AS ‘City’, am.state AS ‘State’, ar.mfr AS ‘Manufacturer’, ar.model AS ‘Model’, am.year_mfr AS ‘Year’ FROM aircraft_master am LEFT JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE am.n_number IS NOT NULL LIMIT 5;
+----------+------------------------------+------------+-------+--------------------+--------------+------+
|N-Number | Owner | City | State | Manufacturer | Model | Year |
+----------+------------------------------+------------+-------+--------------------+--------------+------+
|100 | BENE MARY D | KETCHUM | OK | PIPER | J3C-65 | 1940 |
|10000 | 9AT LLC | NASHVILLE | TN | CIRRUS DESIGN CORP | SR22T | NULL |
|10001 | STOOS ROBERT A | LAKELAND | FL | WACO | ASO | 1928 |
|10004 | ETOS AIR LLC | NEW LONDON | TX | CESSNA | T182T | NULL |
|10006 | COUTCHES ROBERT HERCULES DBA | LIVERMORE | CA | BEECH | D-45 (T-34B) | 1955 |
+----------+------------------------------+------------+-------+--------------------+--------------+------+
5 rows in set (0.00 sec)
Description: Counts aircraft with valid registrations per month, limited to Boeing or Airbus, for dates since 2020-01-01. Uses cert_issue_date as YYYYMMDD and formats month as YYYY-MM.
mysql> SELECT CONCAT(SUBSTRING(am.cert_issue_date,1,4), ‘-’, SUBSTRING(am.cert_issue_date,5,2)) AS cert_month, COUNT(*) AS aircraft_count FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE am.status_code = ‘V’ AND (ar.mfr = ‘BOEING’ OR ar.mfr LIKE ‘%AIRBUS%’) AND am.cert_issue_date IS NOT NULL AND am.cert_issue_date != ’’ AND am.cert_issue_date >= ‘20200101’ GROUP BY CONCAT(SUBSTRING(am.cert_issue_date,1,4), ‘-’, SUBSTRING(am.cert_issue_date,5,2)) ORDER BY cert_month DESC;
+------------+----------------+
|cert_month | aircraft_count |
+------------+----------------+
|2025-09 | 35 |
|2025-08 | 61 |
|2025-07 | 61 |
|2025-06 | 74 |
|2025-05 | 88 |
|2025-04 | 102 |
|2025-03 | 77 |
|2025-02 | 67 |
|2025-01 | 75 |
|2024-12 | 111 |
|2024-11 | 67 |
|2024-10 | 59 |
|2024-09 | 59 |
|2024-08 | 61 |
|2024-07 | 84 |
|2024-06 | 54 |
|2024-05 | 80 |
|2024-04 | 58 |
|2024-03 | 62 |
|2024-02 | 75 |
|2024-01 | 78 |
|2023-12 | 127 |
|2023-11 | 75 |
|2023-10 | 72 |
|2023-09 | 58 |
|2023-08 | 74 |
|2023-07 | 78 |
|2023-06 | 78 |
|2023-05 | 101 |
|2023-04 | 55 |
|2023-03 | 112 |
|2023-02 | 73 |
|2023-01 | 99 |
|2022-12 | 131 |
|2022-11 | 55 |
|2022-10 | 67 |
|2022-09 | 71 |
|2022-08 | 65 |
|2022-07 | 37 |
|2022-06 | 50 |
|2022-05 | 47 |
|2022-04 | 56 |
|2022-03 | 78 |
|2022-02 | 38 |
|2022-01 | 42 |
|2021-12 | 51 |
|2021-11 | 38 |
|2021-10 | 51 |
|2021-09 | 59 |
|2021-08 | 66 |
|2021-07 | 53 |
|2021-06 | 42 |
|2021-05 | 56 |
|2021-04 | 70 |
|2021-03 | 83 |
|2021-02 | 57 |
|2021-01 | 53 |
|2020-12 | 98 |
|2020-11 | 38 |
|2020-10 | 47 |
|2020-09 | 42 |
|2020-08 | 43 |
|2020-07 | 40 |
|2020-06 | 59 |
|2020-05 | 47 |
|2020-04 | 37 |
|2020-03 | 30 |
|2020-02 | 37 |
|2020-01 | 38 |
+------------+----------------+
69 rows in set (0.49 sec)
Description: Produces side-by-side columns for total, Boeing, Airbus, and Others, grouped by certification month since 2020-01-01.
mysql> SELECT CONCAT(SUBSTRING(am.cert_issue_date,1,4), ‘-’, SUBSTRING(am.cert_issue_date,5,2)) AS cert_month, COUNT(*) AS total, SUM(CASE WHEN ar.mfr = ‘BOEING’ THEN 1 ELSE 0 END) AS boeing, SUM(CASE WHEN ar.mfr LIKE ‘%AIRBUS%’ THEN 1 ELSE 0 END) AS airbus, SUM(CASE WHEN ar.mfr != ‘BOEING’ AND ar.mfr NOT LIKE ‘%AIRBUS%’ THEN 1 ELSE 0 END) AS others FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE am.status_code = ‘V’ AND am.cert_issue_date IS NOT NULL AND am.cert_issue_date != ’’ AND am.cert_issue_date >= ‘20200101’ GROUP BY CONCAT(SUBSTRING(am.cert_issue_date,1,4), ‘-’, SUBSTRING(am.cert_issue_date,5,2)) ORDER BY cert_month DESC;
+------------+-------+--------+--------+--------+
|cert_month | total | boeing | airbus | others |
+------------+-------+--------+--------+--------+
|2025-09 | 1030 | 18 | 17 | 995 |
|2025-08 | 3204 | 39 | 22 | 3143 |
|2025-07 | 3103 | 26 | 35 | 3042 |
|2025-06 | 2992 | 48 | 26 | 2918 |
|2025-05 | 3009 | 44 | 44 | 2921 |
|2025-04 | 2986 | 50 | 52 | 2884 |
|2025-03 | 3790 | 46 | 31 | 3713 |
|2025-02 | 2427 | 31 | 36 | 2360 |
|2025-01 | 2689 | 39 | 36 | 2614 |
|2024-12 | 1936 | 73 | 38 | 1825 |
|2024-11 | 2533 | 19 | 48 | 2466 |
|2024-10 | 2878 | 17 | 42 | 2819 |
|2024-09 | 2422 | 31 | 28 | 2363 |
|2024-08 | 2771 | 37 | 24 | 2710 |
|2024-07 | 3021 | 52 | 32 | 2937 |
|2024-06 | 2790 | 29 | 25 | 2736 |
|2024-05 | 3277 | 52 | 28 | 3197 |
|2024-04 | 2723 | 34 | 24 | 2665 |
|2024-03 | 2513 | 30 | 32 | 2451 |
|2024-02 | 2245 | 46 | 29 | 2170 |
|2024-01 | 3094 | 29 | 49 | 3016 |
|2023-12 | 2757 | 60 | 67 | 2630 |
|2023-11 | 2401 | 37 | 38 | 2326 |
|2023-10 | 2549 | 36 | 36 | 2477 |
|2023-09 | 2637 | 36 | 22 | 2579 |
|2023-08 | 3078 | 48 | 26 | 3004 |
|2023-07 | 2374 | 46 | 32 | 2296 |
|2023-06 | 2934 | 56 | 22 | 2856 |
|2023-05 | 3560 | 63 | 38 | 3459 |
|2023-04 | 3092 | 35 | 20 | 3037 |
|2023-03 | 3922 | 61 | 51 | 3810 |
|2023-02 | 3672 | 41 | 32 | 3599 |
|2023-01 | 3497 | 79 | 20 | 3398 |
|2022-12 | 2630 | 96 | 35 | 2499 |
|2022-11 | 2027 | 36 | 19 | 1972 |
|2022-10 | 1995 | 43 | 24 | 1928 |
|2022-09 | 1859 | 42 | 29 | 1788 |
|2022-08 | 2335 | 43 | 22 | 2270 |
|2022-07 | 1563 | 25 | 12 | 1526 |
|2022-06 | 1212 | 32 | 18 | 1162 |
|2022-05 | 1616 | 31 | 16 | 1569 |
|2022-04 | 1460 | 27 | 29 | 1404 |
|2022-03 | 1917 | 49 | 29 | 1839 |
|2022-02 | 1460 | 26 | 12 | 1422 |
|2022-01 | 1812 | 21 | 21 | 1770 |
|2021-12 | 1528 | 28 | 23 | 1477 |
|2021-11 | 1582 | 23 | 15 | 1544 |
|2021-10 | 1646 | 37 | 14 | 1595 |
|2021-09 | 1829 | 28 | 31 | 1770 |
|2021-08 | 2120 | 48 | 18 | 2054 |
|2021-07 | 1839 | 35 | 18 | 1786 |
|2021-06 | 1775 | 28 | 14 | 1733 |
|2021-05 | 1929 | 34 | 22 | 1873 |
|2021-04 | 1961 | 42 | 28 | 1891 |
|2021-03 | 1960 | 47 | 36 | 1877 |
|2021-02 | 1833 | 26 | 31 | 1776 |
|2021-01 | 1686 | 27 | 26 | 1633 |
|2020-12 | 1529 | 52 | 46 | 1431 |
|2020-11 | 1422 | 15 | 23 | 1384 |
|2020-10 | 1400 | 20 | 27 | 1353 |
|2020-09 | 1319 | 25 | 17 | 1277 |
|2020-08 | 1788 | 22 | 21 | 1745 |
|2020-07 | 1406 | 16 | 24 | 1366 |
|2020-06 | 1297 | 37 | 22 | 1238 |
|2020-05 | 1188 | 22 | 25 | 1141 |
|2020-04 | 1472 | 20 | 17 | 1435 |
|2020-03 | 1264 | 17 | 13 | 1234 |
|2020-02 | 1129 | 23 | 14 | 1092 |
|2020-01 | 1673 | 28 | 10 | 1635 |
+------------+-------+--------+--------+--------+
69 rows in set (0.56 sec)
Description: Same as (2), adding a column for Hybrid Lift aircraft (Type Aircraft = ‘H’). This version includes a LIMIT 20 as used above; remove LIMIT for full range.
mysql> SELECT CONCAT(SUBSTRING(am.cert_issue_date,1,4), ‘-’, SUBSTRING(am.cert_issue_date,5,2)) AS cert_month, COUNT(*) AS total, SUM(CASE WHEN ar.mfr = ‘BOEING’ THEN 1 ELSE 0 END) AS boeing, SUM(CASE WHEN ar.mfr LIKE ‘%AIRBUS%’ THEN 1 ELSE 0 END) AS airbus, SUM(CASE WHEN ar.mfr != ‘BOEING’ AND ar.mfr NOT LIKE ‘%AIRBUS%’ THEN 1 ELSE 0 END) AS others, SUM(CASE WHEN am.type_aircraft = ‘H’ THEN 1 ELSE 0 END) AS hybrid_lift FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE am.status_code = ‘V’ AND am.cert_issue_date IS NOT NULL AND am.cert_issue_date != ’’ AND am.cert_issue_date >= ‘20200101’ GROUP BY CONCAT(SUBSTRING(am.cert_issue_date,1,4), ‘-’, SUBSTRING(am.cert_issue_date,5,2)) ORDER BY cert_month DESC LIMIT 20;
+------------+-------+--------+--------+--------+-------------+
|cert_month | total | boeing | airbus | others | hybrid_lift |
+------------+-------+--------+--------+--------+-------------+
|2025-09 | 1030 | 18 | 17 | 995 | 2 |
|2025-08 | 3204 | 39 | 22 | 3143 | 4 |
|2025-07 | 3103 | 26 | 35 | 3042 | 18 |
|2025-06 | 2992 | 48 | 26 | 2918 | 13 |
|2025-05 | 3009 | 44 | 44 | 2921 | 15 |
|2025-04 | 2986 | 50 | 52 | 2884 | 371 |
|2025-03 | 3790 | 46 | 31 | 3713 | 212 |
|2025-02 | 2427 | 31 | 36 | 2360 | 10 |
|2025-01 | 2689 | 39 | 36 | 2614 | 3 |
|2024-12 | 1936 | 73 | 38 | 1825 | 0 |
|2024-11 | 2533 | 19 | 48 | 2466 | 50 |
|2024-10 | 2878 | 17 | 42 | 2819 | 13 |
|2024-09 | 2422 | 31 | 28 | 2363 | 86 |
|2024-08 | 2771 | 37 | 24 | 2710 | 21 |
|2024-07 | 3021 | 52 | 32 | 2937 | 1 |
|2024-06 | 2790 | 29 | 25 | 2736 | 0 |
|2024-05 | 3277 | 52 | 28 | 3197 | 7 |
|2024-04 | 2723 | 34 | 24 | 2665 | 1 |
|2024-03 | 2513 | 30 | 32 | 2451 | 5 |
|2024-02 | 2245 | 46 | 29 | 2170 | 6 |
+------------+-------+--------+--------+--------+-------------+
20 rows in set (0.57 sec)
Description: Shows 10 most recent valid Hybrid Lift aircraft (Type Aircraft = ‘H’) with owner, make/model, serial, and formatted certification date.
mysql> SELECT am.n_number, am.name, ar.mfr, ar.model, am.year_mfr, am.serial_number, am.type_aircraft, CONCAT(SUBSTRING(am.cert_issue_date,1,4), ‘-’, SUBSTRING(am.cert_issue_date,5,2), ‘-’, SUBSTRING(am.cert_issue_date,7,2)) AS cert_date FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE am.type_aircraft = ‘H’ AND am.status_code = ‘V’ ORDER BY am.cert_issue_date DESC LIMIT 10;
+----------+-------------------------------------+------------------------------+-----------+----------+----------------------+---------------+------------+
|n_number | name | mfr | model | year_mfr | serial_number | type_aircraft | cert_date |
+----------+-------------------------------------+------------------------------+-----------+----------+----------------------+---------------+------------+
|805HX | HONDA RESEARCH INSTITUTE USA INC | HONDA RESEARCH INSTITUTE USA | F1 | NULL | 001 | H | 2025-09-06 |
|625RZ | CLEAN CUT HARVESTING LLC | DJI | AGRAS T50 | NULL | 1581F6BUB235J001003G | H | 2025-09-05 |
|2014M | UNIVERSITY OF MARYLAND | EDGE AUTONOMY | PENGUIN-B | NULL | PNB1030 | H | 2025-08-26 |
|246DR | DANS DRONES LLC | DJI | AGRAS T50 | NULL | 1581F6BUB2492001P543 | H | 2025-08-11 |
|399NW | TERRAPLEX PACIFIC NORTHWEST LLC | DJI | AGRAS T50 | NULL | 1581F6BUB246C001QL5T | H | 2025-08-06 |
|251GG | G4 DRONES LLC | DJI | AGRAS T50 | NULL | 1581F6BUB246H0010K6E | H | 2025-08-01 |
|1856A | UNIVERSITY OF MARYLAND UAS RESEARCH | EDGE AUTONOMY | PENGUIN-B | NULL | PNB1031 | H | 2025-07-31 |
|902LU | AEROSPACE ASSETS LLC | DJI | AGRAS T50 | NULL | 1581F6BUB23AG0013PJZ | H | 2025-07-28 |
|695VX | EDGE AUTONOMY SLO LLC | EDGE AUTONOMY SLO LLC | VXE30 | NULL | 695 | H | 2025-07-27 |
|125CR | CR AGWORKS LLC | DJI | AGRAS T50 | NULL | 1581F6BUB245R001U5P2 | H | 2025-07-25 |
+----------+-------------------------------------+------------------------------+-----------+----------+----------------------+---------------+------------+
10 rows in set (0.01 sec)
Description: Lists recent valid Boeing/Airbus aircraft certified in 2025 with cert and last action dates formatted as YYYY-MM-DD.
mysql> SELECT am.n_number, am.name, ar.model, CONCAT(SUBSTRING(am.cert_issue_date,1,4), ‘-’, SUBSTRING(am.cert_issue_date,5,2), ‘-’, SUBSTRING(am.cert_issue_date,7,2)) AS cert_date FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE am.status_code = ‘V’ AND (ar.mfr = ‘BOEING’ OR ar.mfr LIKE ‘%AIRBUS%’) AND am.year_mfr = ‘2025’ ORDER BY am.cert_issue_date DESC LIMIT 20;
+----------+-------------------------------------------+-------------+------------+
|n_number | name | model | cert_date |
+----------+-------------------------------------------+-------------+------------+
|8966S | SOUTHWEST AIRLINES CO | 737-8 | 2025-09-04 |
|17410 | WILMINGTON TRUST COMPANY TRUSTEE | 737-9 | 2025-09-03 |
|17411 | WILMINGTON TRUST CO TRUSTEE | 737-9 | 2025-09-03 |
|57409 | WILMINGTON TRUST CO TRUSTEE | 737-9 | 2025-09-03 |
|847MF | AMERICAN AIRLINES INC | 787-9 | 2025-09-03 |
|849AN | AMERICAN AIRLINES INC | 787-9 | 2025-09-02 |
|8965Q | SOUTHWEST AIRLINES CO | 737-8 | 2025-09-02 |
|311UN | AMERICAN AIRLINES INC | 737-8 | 2025-08-28 |
|17408 | WILMINGTON TRUST COMPANY TRUSTEE | 737-9 | 2025-08-27 |
|825NV | ALLEGIANT AIR LLC | 737-8200 | 2025-08-27 |
|8964L | SOUTHWEST AIRLINES CO | 737-8 | 2025-08-26 |
|17407 | WILMINGTON TRUST CO TRUSTEE | 737-9 | 2025-08-25 |
|22995 | UNITED AIRLINES INC | 787-9 | 2025-08-25 |
|17406 | WILMINGTON TRUST CO TRUSTEE | 737-9 | 2025-08-22 |
|3271J | JETBLUE AIRWAYS CORP | BD-500-1A11 | 2025-08-22 |
|910UP | UNITED PARCEL SERVICE CO | 767-300F | 2025-08-22 |
|991DE | TVPX AIRCRAFT SOLUTIONS INC OWNER TRUSTEE | AS350B3 | 2025-08-22 |
|54538 | UNITED AIRLINES INC | A321-271NX | 2025-08-21 |
|222HN | HEALTHNET AEROMEDICAL SERVICES INC | EC135 P3 | 2025-08-20 |
|256BZ | BREEZE AVIATION GROUP INC | BD-500-1A11 | 2025-08-20 |
+----------+-------------------------------------------+-------------+------------+
20 rows in set (0.08 sec)
Lookup aircraft by exact/partial serial number Description: Returns detailed registration info for aircraft with exact or partial serial number match.
mysql> SELECT am.n_number, am.name, ar.mfr, ar.model, am.year_mfr, am.serial_number, am.type_aircraft, am.status_code, am.cert_issue_date, am.last_action_date, am.city, am.state, am.country, am.eng_mfr_mdl, am.certification, am.type_engine, am.mode_s_code FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE am.serial_number = '42626' OR am.serial_number LIKE '%42626%'\G;
*************************** 1. row ***************************
n_number: 8966S
name: SOUTHWEST AIRLINES CO
mfr: BOEING
model: 737-8
year_mfr: 2025
serial_number: 42626
type_aircraft: 5
status_code: V
cert_issue_date: 20250904
last_action_date: 20250904
city: DALLAS
state: TX
country: US
eng_mfr_mdl: 13120
certification: 1T
type_engine: 5
mode_s_code: 53057331
1 row in set (0.18 sec)
Description: Shows nearby Boeing 737-8 aircraft by serial range with cert dates to infer production cadence.
mysql> SELECT am.n_number, am.name, ar.mfr, ar.model, am.year_mfr, am.serial_number, am.cert_issue_date FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE ar.mfr = 'BOEING' AND ar.model = '737-8' AND am.serial_number BETWEEN '42620' AND '42630' ORDER BY am.serial_number\G;
*************************** 1. row ***************************
n_number: 8963Q
name: SOUTHWEST AIRLINES CO
mfr: BOEING
model: 737-8
year_mfr: 2025
serial_number: 42622
cert_issue_date: 20250701
*************************** 2. row ***************************
n_number: 8966S
name: SOUTHWEST AIRLINES CO
mfr: BOEING
model: 737-8
year_mfr: 2025
serial_number: 42626
cert_issue_date: 20250904
2 rows in set (0.01 sec)
Description: Shows each key field from each table with the top 12 unique values and their occurrence counts in parentheses, consolidated into one comprehensive table.
mysql> SELECT 'aircraft_master' as table_name, 'n_number' as field_name, GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') as top_values FROM (SELECT n_number as value, COUNT(*) as cnt FROM aircraft_master WHERE n_number IS NOT NULL GROUP BY n_number ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_master', 'status_code', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT status_code as value, COUNT(*) as cnt FROM aircraft_master WHERE status_code IS NOT NULL GROUP BY status_code ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_master', 'state', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT state as value, COUNT(*) as cnt FROM aircraft_master WHERE state IS NOT NULL GROUP BY state ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_master', 'type_aircraft', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT type_aircraft as value, COUNT(*) as cnt FROM aircraft_master WHERE type_aircraft IS NOT NULL GROUP BY type_aircraft ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_master', 'type_engine', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT type_engine as value, COUNT(*) as cnt FROM aircraft_master WHERE type_engine IS NOT NULL GROUP BY type_engine ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_master', 'year_mfr', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT year_mfr as value, COUNT(*) as cnt FROM aircraft_master WHERE year_mfr IS NOT NULL AND year_mfr != '' GROUP BY year_mfr ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_master', 'country', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT country as value, COUNT(*) as cnt FROM aircraft_master WHERE country IS NOT NULL GROUP BY country ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_master', 'certification', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT certification as value, COUNT(*) as cnt FROM aircraft_master WHERE certification IS NOT NULL GROUP BY certification ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_reference', 'mfr', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT mfr as value, COUNT(*) as cnt FROM aircraft_reference WHERE mfr IS NOT NULL GROUP BY mfr ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_reference', 'type_acft', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT type_acft as value, COUNT(*) as cnt FROM aircraft_reference WHERE type_acft IS NOT NULL GROUP BY type_acft ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_reference', 'type_eng', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT type_eng as value, COUNT(*) as cnt FROM aircraft_reference WHERE type_eng IS NOT NULL GROUP BY type_eng ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_reference', 'ac_cat', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT ac_cat as value, COUNT(*) as cnt FROM aircraft_reference WHERE ac_cat IS NOT NULL GROUP BY ac_cat ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_reference', 'no_eng', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT no_eng as value, COUNT(*) as cnt FROM aircraft_reference WHERE no_eng IS NOT NULL GROUP BY no_eng ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'aircraft_reference', 'ac_weight', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT ac_weight as value, COUNT(*) as cnt FROM aircraft_reference WHERE ac_weight IS NOT NULL GROUP BY ac_weight ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'engines', 'mfr', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT mfr as value, COUNT(*) as cnt FROM engines WHERE mfr IS NOT NULL GROUP BY mfr ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'engines', 'type', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT type as value, COUNT(*) as cnt FROM engines WHERE type IS NOT NULL GROUP BY type ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'dealers', 'ownership', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT ownership as value, COUNT(*) as cnt FROM dealers WHERE ownership IS NOT NULL GROUP BY ownership ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'dealers', 'state_abbrev', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT state_abbrev as value, COUNT(*) as cnt FROM dealers WHERE state_abbrev IS NOT NULL GROUP BY state_abbrev ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'deregistered_aircraft', 'status_code', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT status_code as value, COUNT(*) as cnt FROM deregistered_aircraft WHERE status_code IS NOT NULL GROUP BY status_code ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'deregistered_aircraft', 'country_mail', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT country_mail as value, COUNT(*) as cnt FROM deregistered_aircraft WHERE country_mail IS NOT NULL GROUP BY country_mail ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'documentation_index', 'doc_type', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT doc_type as value, COUNT(*) as cnt FROM documentation_index WHERE doc_type IS NOT NULL GROUP BY doc_type ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'documentation_index', 'type_collateral', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT type_collateral as value, COUNT(*) as cnt FROM documentation_index WHERE type_collateral IS NOT NULL GROUP BY type_collateral ORDER BY cnt DESC LIMIT 12) t UNION ALL SELECT 'reserved_numbers', 'state', GROUP_CONCAT(CONCAT(value, ' (', cnt, ')') SEPARATOR ', ') FROM (SELECT state as value, COUNT(*) as cnt FROM reserved_numbers WHERE state IS NOT NULL GROUP BY state ORDER BY cnt DESC LIMIT 12) t\G;
*************************** 1. row ***************************
table_name: aircraft_master
field_name: n_number
top_values: 100 (1), 10000 (1), 10001 (1), 10004 (1), 10006 (1), 10007 (1), 10009 (1), 1000A (1), 1000E (1), 1000G (1), 1000H (1), 1000J (1)
*************************** 2. row ***************************
table_name: aircraft_master
field_name: status_code
top_values: V (301669), R (1511), M (1064), 7 (857), 2 (224), N (217), 17 (164), 10 (147), 9 (110), 19 (87), 3 (82), 18 (60)
*************************** 3. row ***************************
table_name: aircraft_master
field_name: state
top_values: TX (28614), CA (25123), FL (21217), DE (10962), WA (10103), AK (9076), GA (8597), UT (8468), AZ (8303), OH (8113), IL (7881), CO (7261)
*************************** 4. row ***************************
table_name: aircraft_master
field_name: type_aircraft
top_values: 4 (218584), 5 (48847), 6 (24588), 2 (5179), 1 (4842), 8 (1902), 7 (1046), H (969), 9 (376), 3 (49), O (21)
*************************** 5. row ***************************
table_name: aircraft_master
field_name: type_engine
top_values: 1 (208755), 5 (26602), 8 (21029), 2 (13894), 10 (11036), 3 (9574), 0 (9051), 7 (4864), 4 (1514), 11 (75), 9 (5), 6 (4)
*************************** 6. row ***************************
table_name: aircraft_master
field_name: year_mfr
top_values: 1946 (8613), 1978 (6864), 1979 (6466), 1977 (6432), 1976 (6350), 1966 (5744), 1975 (5317), 1968 (5012), 1974 (4893), 2007 (4764), 1973 (4752), 1967 (4745)
*************************** 7. row ***************************
table_name: aircraft_master
field_name: country
top_values: US (301955), GB (761), RQ (482), DE (331), AT (100), VI (94), GU (65), CA (47), MP (31), CH (17), MX (12), IE (11)
*************************** 8. row ***************************
table_name: aircraft_master
field_name: certification
top_values: 1N (97126), 1 (42164), 1NU (31742), 42 (29249), 1T (21661), 1U (16729), 1B (4098), 43 (3989), 48A (3659), 31 (3446), 9A (3401), 1NA (2766)
*************************** 9. row ***************************
table_name: aircraft_reference
field_name: mfr
top_values: BOEING (1541), CESSNA (419), BEECH (336), PIPER (261), DOUGLAS (240), LOCKHEED (221), SIKORSKY (197), BELL (161), DJI (159), DEHAVILLAND (151), NORTH AMERICAN (144), FAIRCHILD (143)
*************************** 10. row ***************************
table_name: aircraft_reference
field_name: type_acft
top_values: 4 (71031), 6 (9577), 5 (4732), 1 (2935), 2 (1843), 8 (1330), 7 (1011), 9 (483), 3 (94), H (77), O (12)
*************************** 11. row ***************************
table_name: aircraft_reference
field_name: type_eng
top_values: 1 (69797), 8 (6707), 7 (5543), 0 (3999), 10 (1737), 5 (1695), 2 (1374), 4 (1192), 3 (1022), 11 (35), 9 (17), 6 (7)
*************************** 12. row ***************************
table_name: aircraft_reference
field_name: ac_cat
top_values: 1 (89371), 3 (3503), 2 (251)
*************************** 13. row ***************************
table_name: aircraft_reference
field_name: no_eng
top_values: 1 (82698), 2 (4153), 0 (4006), 4 (1303), 8 (291), 6 (286), 3 (277), 5 (47), 12 (17), 10 (13), 9 (12), 16 (8)
*************************** 14. row ***************************
table_name: aircraft_reference
field_name: ac_weight
top_values: CLASS 1 (87967), CLASS 3 (2890), CLASS 4 (1456), CLASS 2 (812)
*************************** 15. row ***************************
table_name: engines
field_name: mfr
top_values: LYCOMING (868), CONT MOTOR (408), P & W (352), ROLLS-ROYC (300), WRIGHT (282), GE (216), P&W CANADA (203), HONEYWELL (197), ALLIEDSIGN (153), GARRETT (120), ALLISON (113), CFM INTL (103)
*************************** 16. row ***************************
table_name: engines
field_name: type
top_values: 1 (2398), 2 (749), 5 (712), 3 (397), 4 (191), 8 (167), 7 (70), 10 (37), 11 (4), 0 (1), 9 (1)
*************************** 17. row ***************************
table_name: dealers
field_name: ownership
top_values: 3 (4244), 7 (3606), 1 (2420), 0 (1663), 2 (150), 4 (96), 8 (13)
*************************** 18. row ***************************
table_name: dealers
field_name: state_abbrev
top_values: FL (2193), CA (1135), TX (598), CO (508), TN (414), AR (385), MO (301), DE (284), PA (222), MI (213), GA (210), NY (201)
*************************** 19. row ***************************
table_name: deregistered_aircraft
field_name: status_code
top_values: V (185793), 16 (43739), A (36939), 29 (28562), 18 (17702), 2 (11196), 22 (10269), 7 (8948), 17 (5772), M (4594), 10 (3524), 20 (3113)
*************************** 20. row ***************************
table_name: deregistered_aircraft
field_name: country_mail
top_values: US (231403), CA (1004), RQ (836), BE (756), GB (731), MX (335), DE (292), VI (209), AU (181), GU (156), BR (148), AR (109)
*************************** 21. row ***************************
table_name: documentation_index
field_name: doc_type
top_values: BOS (5058), S/A (2509), REL (1729), DIS (203), CRT (36), REP (5)
*************************** 22. row ***************************
table_name: documentation_index
field_name: type_collateral
top_values: 1 (6870), 2 (1920), 9 (531), 3 (191), 4 (26), 5 (2)
*************************** 23. row ***************************
table_name: reserved_numbers
field_name: state
top_values: DC (51257), FL (9052), OK (6444), TX (4327), CA (3613), WA (2266), OH (2056), TN (1507), KS (1484), VA (1377), GA (1327), AZ (1153)
23 rows in set (0.67 sec)
mysql> SELECT ar.model, COUNT(*) as registered_count, CASE WHEN ar.type_acft = ‘4’ THEN ‘Single Engine’ WHEN ar.type_acft = ‘5’ THEN ‘Multi Engine’ ELSE ‘Other’ END AS engine_type, CASE WHEN ar.model LIKE ‘737%’ THEN ‘737 Family’ WHEN ar.model LIKE ‘%STEARMAN%’ OR ar.model LIKE ‘PT-%’ OR ar.model LIKE ‘A75%’ OR ar.model LIKE ‘B75%’ OR ar.model LIKE ‘E75%’ OR ar.model LIKE ‘D75%’ THEN ‘Stearman Trainers’ WHEN ar.model LIKE ‘757%’ THEN ‘757 Family’ WHEN ar.model LIKE ‘767%’ THEN ‘767 Family’ WHEN ar.model LIKE ‘777%’ THEN ‘777 Family’ WHEN ar.model LIKE ‘787%’ THEN ‘787 Family’ WHEN ar.model LIKE ‘747%’ THEN ‘747 Family’ WHEN ar.model LIKE ‘717%’ THEN ‘717 Family’ WHEN ar.model REGEXP ‘1{1,2}[0-9]{1,2}$’ AND ar.model NOT REGEXP ‘^(737|747|757|767|777|787|717)’ THEN ‘Historical/Classic’ ELSE ‘Other Boeing’ END AS aircraft_family FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE ar.mfr = ‘BOEING’ AND ar.type_acft IN (‘4’, ‘5’) AND am.status_code = ‘V’ GROUP BY ar.model, ar.type_acft ORDER BY registered_count DESC LIMIT 20;
+-------------+------------------+---------------+-------------------+
|model | registered_count | engine_type | aircraft_family |
+-------------+------------------+---------------+-------------------+
|A75N1(PT17) | 746 | Single Engine | Stearman Trainers |
|737-8 | 504 | Multi Engine | 737 Family |
|737-823 | 278 | Multi Engine | 737 Family |
|E75 | 255 | Single Engine | Stearman Trainers |
|737-7H4 | 253 | Multi Engine | 737 Family |
|B75N1 | 237 | Single Engine | Stearman Trainers |
|737-9 | 202 | Multi Engine | 737 Family |
|767-300F | 142 | Multi Engine | 767 Family |
|737-824 | 135 | Multi Engine | 737 Family |
|737-800 | 132 | Multi Engine | 737 Family |
|737-924ER | 130 | Multi Engine | 737 Family |
|737-8H4 | 125 | Multi Engine | 737 Family |
|717-200 | 115 | Multi Engine | 717 Family |
|737-900ER | 101 | Multi Engine | 737 Family |
|A75 | 93 | Single Engine | Stearman Trainers |
|787-9 | 93 | Multi Engine | 787 Family |
|E75N1 | 79 | Single Engine | Stearman Trainers |
|757-24APF | 75 | Multi Engine | 757 Family |
|787-8 | 74 | Multi Engine | 787 Family |
|737-832 | 73 | Multi Engine | 737 Family |
+-------------+------------------+---------------+-------------------+
20 rows in set (0.03 sec)
SELECT ar.model, COUNT(*) as registered_count, CASE WHEN ar.model LIKE ‘737%’ THEN ‘737 Family’ WHEN ar.model LIKE ‘%STEARMAN%’ OR ar.model LIKE ‘PT-%’ OR ar.model LIKE ‘A75%’ OR ar.model LIKE ‘B75%’ OR ar.model LIKE ‘E75%’ OR ar.model LIKE ‘D75%’ THEN ‘Stearman Trainers’ WHEN ar.model LIKE ‘757%’ THEN ‘757 Family’ WHEN ar.model LIKE ‘767%’ THEN ‘767 Family’ WHEN ar.model LIKE ‘777%’ THEN ‘777 Family’ WHEN ar.model LIKE ‘787%’ THEN ‘787 Family’ WHEN ar.model LIKE ‘747%’ THEN ‘747 Family’ WHEN ar.model LIKE ‘717%’ THEN ‘717 Family’ WHEN ar.model REGEXP ‘2{1,2}[0-9]{1,2}$’ AND ar.model NOT REGEXP ‘^(737|747|757|767|777|787|717)’ THEN ‘Historical/Classic’ ELSE ‘Other Boeing’ END AS aircraft_family FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE ar.mfr = ‘BOEING’ AND ar.type_acft = ‘4’ AND am.status_code = ‘V’ GROUP BY ar.model ORDER BY registered_count DESC LIMIT 10;
+-------------+------------------+-------------------+
|model | registered_count | aircraft_family |
+-------------+------------------+-------------------+
|A75N1(PT17) | 746 | Stearman Trainers |
|E75 | 255 | Stearman Trainers |
|B75N1 | 237 | Stearman Trainers |
|A75 | 93 | Stearman Trainers |
|E75N1 | 79 | Stearman Trainers |
|A75N1 | 57 | Stearman Trainers |
|D75N1 | 35 | Stearman Trainers |
|PT-17 | 34 | Stearman Trainers |
|A75L300 | 33 | Stearman Trainers |
|A75L3 | 32 | Stearman Trainers |
+-------------+------------------+-------------------+
10 rows in set (0.02 sec)
SELECT ar.model, COUNT(*) as registered_count, CASE WHEN ar.model LIKE ‘737%’ THEN ‘737 Family’ WHEN ar.model LIKE ‘%STEARMAN%’ OR ar.model LIKE ‘PT-%’ OR ar.model LIKE ‘A75%’ OR ar.model LIKE ‘B75%’ OR ar.model LIKE ‘E75%’ OR ar.model LIKE ‘D75%’ THEN ‘Stearman Trainers’ WHEN ar.model LIKE ‘757%’ THEN ‘757 Family’ WHEN ar.model LIKE ‘767%’ THEN ‘767 Family’ WHEN ar.model LIKE ‘777%’ THEN ‘777 Family’ WHEN ar.model LIKE ‘787%’ THEN ‘787 Family’ WHEN ar.model LIKE ‘747%’ THEN ‘747 Family’ WHEN ar.model LIKE ‘717%’ THEN ‘717 Family’ WHEN ar.model REGEXP ‘3{1,2}[0-9]{1,2}$’ AND ar.model NOT REGEXP ‘^(737|747|757|767|777|787|717)’ THEN ‘Historical/Classic’ ELSE ‘Other Boeing’ END AS aircraft_family FROM aircraft_master am JOIN aircraft_reference ar ON am.mfr_mdl_code = ar.code WHERE ar.mfr = ‘BOEING’ AND ar.type_acft = ‘5’ AND am.status_code = ‘V’ GROUP BY ar.model ORDER BY registered_count DESC LIMIT 10;
+-----------+------------------+-----------------+
|model | registered_count | aircraft_family |
+-----------+------------------+-----------------+
|737-8 | 504 | 737 Family |
|737-823 | 278 | 737 Family |
|737-7H4 | 253 | 737 Family |
|737-9 | 202 | 737 Family |
|767-300F | 142 | 767 Family |
|737-824 | 135 | 737 Family |
|737-800 | 132 | 737 Family |
|737-924ER | 130 | 737 Family |
|737-8H4 | 125 | 737 Family |
|717-200 | 115 | 717 Family |
+-----------+------------------+-----------------+
10 rows in set (0.03 sec)
This comprehensive analysis of the FAA aircraft registration database reveals significant insights into the US civil aviation landscape. The database contains 910,788 total records across 7 tables, representing one of the most complete datasets of aircraft registration information available.
The analysis reveals a highly concentrated aircraft registration pattern:
The aircraft manufacturing sector leaders are:
Recent manufacturing data reveals important industry patterns: