TEC-DATA86-07 · Lesson 3 · 12 clock hours · lab
Data Profiling: Measuring Quality Dimensions
Objective. Students will use SQL aggregate queries and an open-source profiling tool to measure the six DAMA data-quality dimensions (completeness, uniqueness, timeliness, validity, accuracy, consistency) against a realistic dirty dataset.
⚠ Pending professional review
This lesson, its worked examples and its practice questions has not yet been verified by an industry-certified professional or by a certification or approval body. It is a study draft and may contain errors. Do not use it as instructions for work on a job site or on live equipment. Always follow your instructor, your supervising professional, and current official references and regulations.
VoTechWorks program approval and accreditation are still in progress. Credentials are issued only by the certifying bodies named in each program, after their own exams.
What Is Data Profiling?
Data profiling is the process of examining a dataset and collecting statistics that reveal its actual condition. Before you can fix data problems, you must measure them. Profiling answers questions like: How many rows are missing a customer email? Are order IDs truly unique? Do date values fall within a plausible range? The results feed directly into a data-quality assessment, which guides remediation priorities.
In this lab you work with a 50,000-row synthetic dataset of customer and order records loaded into a PostgreSQL staging schema. You measure quality using two methods — hand-written SQL and the open-source Python library Great Expectations — then reconcile the findings.
---
The Six DAMA Data-Quality Dimensions
DAMA DMBOK defines six dimensions commonly used to evaluate data quality. Each dimension answers a different question about the data.
1. Completeness — Are expected values present? A NULL or blank where a value is required is a completeness failure. Measured by NULL rate: `COUNT(*) - COUNT(column)` divided by total rows.
2. Uniqueness — Does each record (or key) appear exactly once? Duplicate primary keys or duplicate customer records violate uniqueness. Measured by comparing `COUNT(*)` against `COUNT(DISTINCT key_column)`.
3. Timeliness — Is the data available when needed and does it reflect the current state of the world? In a staging table you may measure timeliness by checking whether `order_date` values fall within an expected freshness window, or whether records loaded more than a defined threshold after the event date are flagged as late.
4. Validity — Do values conform to the defined format, type, or domain? Examples: a ZIP code that contains letters, an email address missing the `@` symbol, a status code outside the allowed set. SQL `SIMILAR TO`, `REGEXP_LIKE`, or `NOT IN` clauses can flag violations.
5. Accuracy — Do values correctly reflect the real-world entity? True accuracy requires a trusted reference source. In a profiling exercise you approximate it by checking referential integrity (order rows with no matching customer) or known business rules (a birth year of 1850 is implausible).
6. Consistency — Do related values agree across fields or systems? Example: `ship_date` earlier than `order_date`, or `state` code inconsistent with `zip_code` prefix. Consistency checks often use self-joins or conditional expressions.
---
Scoring Dimensions
A simple 0–100 score is calculated as:
> Score = ((Conforming rows) / (Total rows)) × 100
Round to one decimal place. A score of 95.0 for completeness on the `email` column means 5% of email values are NULL or blank. Scores must be backed by exact row counts so they can be reproduced and audited.
---
Manual SQL Profiling — Key Patterns
Load the CSV into a staging schema named `staging` with table `customer_orders`. Then run queries such as:
```sql
-- Completeness: NULL rate for email
SELECT
COUNT(*) AS total_rows,
COUNT(email) AS populated,
ROUND(COUNT(email)::numeric / COUNT() 100, 1) AS completeness_score
FROM staging.customer_orders;
-- Uniqueness: duplicate order_id count
SELECT order_id, COUNT(*) AS occurrences
FROM staging.customer_orders
GROUP BY order_id
HAVING COUNT(*) > 1;
-- Validity: ZIP codes not matching 5-digit pattern
SELECT COUNT(*) AS invalid_zip
FROM staging.customer_orders
WHERE zip_code !~ '^[0-9]{5}$';
-- Consistency: ship_date before order_date
SELECT COUNT(*) AS inconsistent_dates
FROM staging.customer_orders
WHERE ship_date < order_date;
```
Record row counts for every check. Never modify the staging table while profiling — you are measuring the raw incoming data.
---
Automated Profiling with Great Expectations
Great Expectations (GX) is a Python library that lets you define expectations — assertions about your data — and then validate them, producing an HTML report. Install it in your project virtual environment:
```bash
pip install great_expectations
```
Connect GX to your PostgreSQL table, use `profile()` to auto-generate a baseline expectation suite, then run `validate()`. The HTML Data Docs report shows passing and failing expectations with row-level counts. Compare these findings against your manual SQL results: both methods should flag the same issues. Discrepancies indicate either a query logic error or a GX configuration issue — investigate before finalizing your report.
---
Writing the Data-Quality Assessment Report
Use the provided report template. For each of the six dimensions:
1. State the column(s) checked and the business rule tested.
2. Record exact row counts (numerator and denominator).
3. Calculate and state the dimension score (0–100).
4. Describe the business impact of the issue (e.g., "missing emails prevent marketing campaigns from reaching ~3,200 customers").
After scoring all dimensions, rank the top five issues by business impact — not just by row count. A 2% error rate in `customer_id` referential integrity may be more harmful than a 10% NULL rate in a non-critical field.
---
Workplace and Lab Safety
This lab uses production-like data volumes on shared infrastructure. Follow these practices:
- Data handling: The synthetic dataset is designed for training and contains no real personal information. Even so, treat any dataset labeled "customer data" as sensitive. Do not share files outside the lab environment.
- System resource safety: Large aggregate queries on 50,000 rows are low-risk, but always test queries on a `LIMIT 100` sample first before running against the full table to avoid locking shared database resources.
- Virtual environment discipline: Install Python packages only inside a project virtual environment (`venv`). Never install packages system-wide on shared lab machines.
- Version control: Save all SQL scripts and the GX configuration file. Losing your scripts means you cannot reproduce your scores — reproducibility is a professional and audit requirement in data governance roles.
Key terms10
Data ProfilingThe systematic examination of a dataset to collect statistics and metadata that reveal its actual condition, including NULL rates, duplicate counts, and format violations.
CompletenessA DAMA data-quality dimension measuring whether expected values are present; commonly expressed as the percentage of non-NULL, non-blank values in a required field.
UniquenessA DAMA data-quality dimension measuring whether each record or key value appears exactly once in the dataset, with no unintended duplicates.
ValidityA DAMA data-quality dimension measuring whether values conform to the defined format, data type, or allowable domain (e.g., a proper email format or an approved status code).
ConsistencyA DAMA data-quality dimension measuring whether related values agree with each other across fields or systems (e.g., ship_date must not precede order_date).
Great ExpectationsAn open-source Python library used to define, validate, and document data-quality assertions (called expectations) against datasets, producing automated HTML reports.
Expectation SuiteIn Great Expectations, a named collection of assertions about a dataset — for example, that a column has no NULLs or that values fall within a specified range.
Staging SchemaA database schema used to hold raw, unvalidated data loaded from an external source before it is cleansed or moved to production tables.
Dimension ScoreA numeric value from 0 to 100 representing the percentage of rows that conform to a specific data-quality dimension, calculated as (conforming rows ÷ total rows) × 100.
Business ImpactThe practical consequence of a data-quality issue on business operations, decisions, or customer experience; used to prioritize which issues to remediate first.
Worked examples4
1. A staging table has 50,000 rows. A query returns COUNT(email) = 47,340. Calculate the completeness score for the email column, and state how many rows have a missing email.
- Identify total rows: 50,000.
- Identify populated (non-NULL) rows: 47,340.
- Calculate missing rows: 50,000 − 47,340 = 2,660 rows are NULL.
- Apply the completeness score formula: (47,340 ÷ 50,000) × 100 = 94.68.
- Round to one decimal place: 94.7.
Answer: Completeness score = 94.7 (out of 100); 2,660 rows have a missing email value.
2. A uniqueness check on order_id finds 50,000 total rows but only 49,612 distinct order_id values. Calculate the uniqueness score and the number of duplicate order_id rows.
- Identify total rows: 50,000.
- Identify distinct key values: 49,612.
- Rows that are duplicates (i.e., rows beyond the first occurrence): 50,000 − 49,612 = 388 duplicate rows.
- Apply the uniqueness score formula: (49,612 ÷ 50,000) × 100 = 99.224.
- Round to one decimal place: 99.2.
Answer: Uniqueness score = 99.2 (out of 100); 388 rows share an order_id with at least one other row.
3. A validity check using a regex finds 1,850 rows where zip_code does not match the pattern '^[0-9]{5}$' out of 50,000 total rows. Calculate the validity score for the zip_code column.
- Identify total rows: 50,000.
- Identify invalid rows: 1,850.
- Calculate conforming rows: 50,000 − 1,850 = 48,150.
- Apply the validity score formula: (48,150 ÷ 50,000) × 100 = 96.3.
- Round to one decimal place: 96.3.
Answer: Validity score for zip_code = 96.3 (out of 100); 1,850 ZIP code values fail the 5-digit numeric format check.
4. A consistency check finds 320 rows where ship_date < order_date out of 50,000 total rows. Calculate the consistency score for this rule, and explain how you would prioritize this issue in a business-impact ranking.
- Identify total rows: 50,000.
- Identify inconsistent rows: 320.
- Calculate conforming rows: 50,000 − 320 = 49,680.
- Apply the consistency score formula: (49,680 ÷ 50,000) × 100 = 99.36.
- Round to one decimal place: 99.4.
- For business-impact ranking: even though the row count (320, or 0.6%) is relatively small, a ship_date before order_date is a logical impossibility that could corrupt fulfillment reporting, customer communications, and SLA calculations — warranting a high business-impact priority despite the low percentage.
Answer: Consistency score = 99.4 (out of 100); despite the high score, the 320 impossible date pairs carry high business impact and should rank near the top of the remediation list.
The math in this lesson1
Learners compute a completeness score as the percent of non-null rows.
7.RP.3
In class: Load a provided 50,000-row CSV of synthetic customer and order data into a PostgreSQL staging schema and write SQL queries measuring NULL rates, duplicate key counts, format violations, and out-of-range values for each dimension. · Run the Great Expectations open-source library (Python) against the same staging table to generate an automated expectation suite and HTML report; compare findings with manual SQL results. · Document all findings in a data-quality assessment report template, scoring each dimension on a 0–100 scale and prioritizing the top five issues by business impact.
Materials: PostgreSQL 15, Python 3.x, Great Expectations library, DBeaver CE, provided dirty CSV dataset, data-quality report template, DAMA DMBOK quality dimensions reference card
Check: SQL scripts execute without error, profiling report identifies at least 8 distinct quality issues across at least 4 dimensions, and dimension scores are justified with row counts; instructor verifies report accuracy — at least 6 of 8 issues must match instructor key to pass.
Practice check8
Answer each question, then check it. Nothing is recorded; this is your own practice.
Record this lesson on my transcript. Sign in with your key and enrollment email to record lessons (enroll free if you have no key). This page stays open to read and practise.