Data profiling
Data profiling is the process of examining a dataset to understand its structure, content, and quality — things like data types, value distributions, null rates, and cardinality — before using it for analysis or building pipelines on top of it.
Overview
Data profiling is the systematic analysis of a dataset's structure and content: column types, value ranges, null and distinct counts, patterns, and distributions. It's usually the first step before writing transformation logic, designing a schema, or trusting a new data source, because it surfaces problems (missing values, inconsistent formats, unexpected outliers) before they become bugs downstream.
Profiling can be manual (running a handful of COUNT, MIN/MAX, and COUNT(DISTINCT ...) queries) or automated with dedicated tooling. Either way, the goal is the same: build a quick statistical picture of every column so you know what you're actually working with, not just what the schema or documentation claims.
What a profile typically includes
- Type and format: is a "date" column actually parseable as a date, or a mix of formats?
- Completeness: null counts and null percentage per column
- Cardinality: number of distinct values, useful for spotting near-constant columns or high-cardinality keys
- Distribution: min, max, mean, standard deviation, and quantiles for numeric columns
- Value patterns: most frequent values, sample values, and outliers
Profiling with DuckDB
DuckDB has a built-in SUMMARIZE command that computes most of this in one shot, over a table or any query:
Copy code
SUMMARIZE orders;
-- or summarize the result of a query
SUMMARIZE SELECT * FROM read_parquet('s3://bucket/orders/*.parquet');
SUMMARIZE returns one row per column with column_name, column_type, min, max, approx_unique, avg, std, q25, q50, q75, count, and null_percentage. Because DuckDB can query CSV, Parquet, and JSON files directly, this works equally well against a local file, an S3 path, or an existing table — so profiling a brand-new dataset is often just one line:
Copy code
SUMMARIZE read_csv('data/raw/customers.csv');
For a targeted check, you can still write explicit queries, e.g. finding the null rate for one column:
Copy code
SELECT
COUNT(*) AS total_rows,
COUNT(*) - COUNT(email) AS null_emails,
ROUND(100.0 * (COUNT(*) - COUNT(email)) / COUNT(*), 2) AS null_pct
FROM customers;
Why it matters
Profiling early catches issues that are expensive to discover later: a "unique" ID column that isn't actually unique, a numeric column stored as text, or a date field with a handful of malformed rows that would silently break a join. It also informs decisions like which columns need data cleansing, what constraints to enforce, and where to add data quality tests in a pipeline.
Related terms
Data quality is the degree to which data is accurate, complete, consistent, timely, and fit for the purposes it's used for—dashboards, models, and operational decisions.
NULL →NULL represents a missing, unknown, or inapplicable value in SQL -- it is not the same as zero, an empty string, or false, and requires special comparison operators like IS NULL.
Cardinality →Cardinality refers to the number of distinct values in a column or dataset, or, in data modeling, the nature of a relationship between two tables (such as one-to-many).
UNIQUE constraint →A UNIQUE constraint ensures that all values in a column, or combination of columns, are distinct across every row in a table.
column →A column represents a single field or attribute in a database table or DataFrame that contains values of the same data type.
HyperLogLog →HyperLogLog is a probabilistic algorithm for estimating the number of distinct elements in a large dataset (cardinality) using a small, fixed amount of memory, at the cost of a small, predictable error margin.
FAQS
Data profiling is the diagnostic step: it describes what's in a dataset (types, nulls, distributions, cardinality). Data quality is the broader discipline of ensuring the data meets defined standards (accuracy, completeness, consistency) over time, often using rules and tests that profiling results help you define.
Yes. DuckDB can run SUMMARIZE directly against a query over read_csv, read_parquet, or read_json, so you can profile a file in place without an explicit load or import step.
It's an approximate count of distinct values in the column, computed using a probabilistic algorithm (HyperLogLog) rather than an exact COUNT(DISTINCT ...), which makes it fast even on large tables at the cost of small estimation error.
